I have task to make method that:
get numbers from string
every number is equal to its summed sub-numbers
now sort these sums
display the sorted sums and their original values
I made that function:
void orderWeight(const std::string &strng)
{
std::vector<pair<int, int>> result;
int r{}, rr{}, rrr{};
std::stringstream ss(strng);
while(ss>>r){
rrr = r;
while(r!=0){
rr += r%10;
r /= 10;
}
result.push_back( make_pair(rr, rrr));
rr = 0;
r = 0;
}
std::sort( result.begin(), result.end());
for( int i=0; i<result.size();i++){
cout<<result[i].first<<" "<<result[i].second<<endl;
}
}
This function for arguments - 56 65 74 100 99 68 86 180 90 returns :
1 100
9 90
9 180
11 56
11 65
11 74
14 68
14 86
18 99
But I don't want to sort it by first value THEN by second as You can see in
9 90
9 180
If two numbers are the same, don't sort them by second value, just how are they in a string.
How can I make it happen?
You can make it happen by providing a predicate to sort that tells it how to sort. For example, a simple lambda:
std::sort( result.begin(), result.end(),
[](const auto& lhs, const auto& rhs) {
return lhs.first < rhs.first;
});
The above will sort only by the first value.
See also: https://en.cppreference.com/w/cpp/algorithm/sort
class DataStorage{
// 0 1 2 3 4 5 6 7 8
string Data[20][4]={{"Wee","50","1","First"},{"Wee","22","2","First"},
// 9 10 11 12 13 14 15 16
{"Jason","26","3","First"},{"Krappa","12","4","First"},
// 17 18 19 20 21 22 23 24
{" "," ","5","First"},{" "," ","6","Economy"},
//25 26 27 28 29 30 31 32
{"Kappa","15","7","Economy"},{"Eraser","17","8","Economy"},
//33 34 35 36 37 38 39 40
{" "," ","9","Economy"},{"Morty"," ","10","Economy"},
//41 42 43 44 45 46 47 48
{"Rick"," ","11","Economy"},{"Amanda","10","12","Economy"},
//49 50 51 52 53 54 55 56
{"Lee","","13","Economy"},{"MingLee"," ","14","Economy"},
//57 58 59 60 61 62 63 64
{"Beauty"," ","15","Economy"},{"S4head"," ","16","Economy"},
//65 66 67 68 69 70 71 72
{"Ivan"," ","17","Economy"},{"Dex"," ","18","Economy"},
//73 74 75 76 77 78 79 80
{"Chua"," ","19","Economy"},{"Haha"," ","20","Economy"},};
};
int main(){
}
How do I call the value in array and change the value in array? Do I need to make some function to get value from the input and pass it into a variable in class and set it into my array?
I'm not sure what you're asking when you say How do I call the value in array and change the value in array? but I think you're asking how do you change the value of an array element.
To modify an array element you assign the array's index to what you're changing the array's element to; however, remember that C++ arrays are 0-index arrays meaning when you start counting their elements at 0. For example the following code modifies the element at index 5. Live preview
#include <iostream>
int array[10] = {1, 5, 33, 7, -23, 2, 8, 54, 19, 2};
int main() {
std::cout << array[5] << std::endl;
array[5] = 100; // Set the value of the element at index 5 to 100
std::cout << array[5] << std::endl;
return 0;
}
If you want to have Data as a class member of DataStorage you have to initialize it in the member initialization list. I also highly recommend to use an abstraction for the bare array, like std::array. This allows to use bounds-checked access with the at() function. You can then access Data and change it's contents.
#include <array>
#include <iostream>
#include <string>
class DataStorage
{
public:
std::array<std::array<std::string,4>,20> Data;
DataStorage() : Data({{
{{"Wee","50","1","First"}},
{{"Wee","22","2","First"}},
{{"Jason","26","3","First"}},
{{"Krappa","12","4","First"}},
{{" "," ","5","First"}},
{{" "," ","6","Economy"}},
{{"Kappa","15","7","Economy"}},
{{"Eraser","17","8","Economy"}},
{{" "," ","9","Economy"}},
{{"Morty"," ","10","Economy"}},
{{"Rick"," ","11","Economy"}},
{{"Amanda","10","12","Economy"}},
{{"Lee","","13","Economy"}},
{{"MingLee"," ","14","Economy"}},
{{"Beauty"," ","15","Economy"}},
{{"S4head"," ","16","Economy"}},
{{"Ivan"," ","17","Economy"}},
{{"Dex"," ","18","Economy"}},
{{"Chua"," ","19","Economy"}},
{{"Haha"," ","20","Economy"}}
}}) {}
};
int main()
{
DataStorage d;
std::cout << d.Data.at(10).at(2) << '\n'; // prints 11
d.Data.at(10).at(2) = "1729";
std::cout << d.Data.at(10).at(2) << '\n'; // prints 1729
}
In the function below I have made use of http_client from cpprestsdk (https://github.com/Microsoft/cpprestsdk) to make http requests to a network camera. The function below is probably a callback called by the lcm library (http://lcm-proj.github.io/) when a certain request is made.
I had problems with line 11. I was previously using the new operator:
auto init_session_response = new init_session_response_t;
to create the pointer and manually delete it just before exiting the function.
But I got a access violation exception when trying to modify the init_session_response object in the pplx task continuation at line 49.
init_session_response->status_code =
ptz_camera::status_codes_t::OK;
This problem went away when I started using std::shared_ptr. Can someone explain to me why using shared_ptr solved the problem? Should the http_client* also be created using std::shared_ptr?
1 void lcm_handler::on_init_session_req(const lcm::ReceiveBuffer* rbuff,
2 const std::string& channel,
3 const ptz_camera::init_session_request_t* req)
4 {
5 std::cout << "Received init session req on channel: " << channel <<
6 "; Camera: " << req->ip_address << std::endl;
7
8 auto ip_address = req->ip_address;
9
10 // Note use of std::shared_ptr
11 auto init_session_response = make_shared<ptz_camera::init_session_response_t>();
12
13 auto key_position = this->ip_client_map.find(ip_address);
14 if (key_position == ip_client_map.end())
15 {
16 std::cout << "Creating a new client for the ip: "
17 << req->ip_address << endl;
18
19 wstring username = this->convert_to_wstring(req->username);
20 wstring password = this->convert_to_wstring(req->password);
21
22 wstring main_uri = L"http://" + convert_to_wstring(ip_address);
23 auto config = http_client_config();
24 auto login = credentials(username, password);
25 config.set_credentials(login);
26 config.set_timeout(std::chrono::milliseconds(500));
27
28 http_client* client = new http_client(main_uri, config);
29 std::cout << "Client created...\n";
30
31 uri_builder uri = uri_builder(U("/") + uri_constants::stw_cgi).
32 append_path(uri_constants::attributes_cgi).append_path(uri_constants::attributes);
33
34 auto request = uri.to_string();
35
36 client->request(methods::GET, request)
37 .then([this, ip_address, client, init_session_response]
38 (pplx::task<http_response> request_task) -> pplx::task<wstring>
39 {
40 try
41 {
42 auto response = request_task.get();
43 if (response.status_code() == status_codes::OK)
44 {
45 std::cout << "Saving client...";
46 this->ip_client_map[ip_address] = client;
47 std::cout << "success.\n";
48
49 init_session_response->status_code =
50 ptz_camera::status_codes_t::OK;
51 }
52
53 else
54 {
55 cout << "GET request to client failed! HTTP Error: "
56 << response.status_code() << std::endl;
57
58 init_session_response->status_code =
59 ptz_camera::status_codes_t::ERR;
60 }
61
62 return response.extract_string();
63 }
64
65 catch (const exception& e)
66 {
67 cout << "Caught exception: " << e.what() << endl;
68 return create_task([e, this]() -> wstring
69 {
70 return convert_to_wstring(e.what());
71 });
72 }
73
74 })
75 .then([init_session_response, this](wstring response)
76 {
77 string n = this->convert_to_string(response);
78 init_session_response->response_message = n;
79 });
80 }
81
82
83 else
84 {
85 string message = "Client for ip: " + req->ip_address + " already exists\n";
86 cout << message << endl;
87 init_session_response->response_message = message;
88 init_session_response->status_code = ptz_camera::status_codes_t::OK;
89 }
90
91 this->lcm->publish(ptz_camera_channels::init_session_res_channel,
92 init_session_response.get());
93}
When you get violation access error, you must have deleted the pointer in some place in your code (e.g. in some then lambdas), but you did not post your code using raw pointer so I can not say which line.
By using std::shared_ptr, when it's passed to the lambda, it's captured by value, so it increase the use_count and ensures that init_session_response is valid and not destructed in the labmda, which solves the issue.
I have a float array Eigen::ArrayXf which I need to decimate (i.e. pick 1 out of f.i. 8 samples).
Eigen::ArrayXf decimatedSignal = Eigen::Map<Eigen::ArrayXf, 0, Eigen::InnerStride<8> >(signal.data(), length, 1).eval();
which works, with a caveat: I need to know how long length is, and it can be specified too long, leading to runtime errors.
Q: is there a way to decimate all that is possible, so that resultant length is == signal.size() / 8 ?
Two things. You are using the c'tor for mapping a matrix:
Map (
PointerArgType dataPtr,
Index nbRows,
Index nbCols,
const StrideType & a_stride = StrideType()
)
Constructor in the dynamic-size matrix case.
Parameters
dataPtr pointer to the array to map
nbRows the number of rows of the matrix expression
nbCols the number of columns of the matrix expression
a_stride optional Stride object, passing the strides.
I think you want the c'tor for a vector:
Map ( PointerArgType dataPtr,
Index a_size,
const StrideType & a_stride = StrideType()
)
Constructor in the dynamic-size vector case.
Parameters
dataPtr pointer to the array to map
a_size the size of the vector expression
a_stride optional Stride object, passing the strides.
The second thing is that you want length == signal.size())/8. Is that always a whole integer, or are you rounding up? If the data is 16 in length and you want the positions [0] and [8], then use 1+(signal.size()-1)/8 as the length parameter:
Eigen::ArrayXf decimatedSignal = Eigen::Map<Eigen::ArrayXf, 0, Eigen::InnerStride<8> >(signal.data(), 1+((signal.size()-1)/8) ).eval();
For example:
#include <Eigen/Core>
#include <iostream>
using std::cout;
using std::endl;
int main(int argc, char *argv[])
{
Eigen::VectorXf signal;
signal.setLinSpaced(64, 0.0, 63.);
cout << "Original signal:" << endl << signal.transpose() << endl;
Eigen::ArrayXf decimatedSignal = Eigen::Map<Eigen::ArrayXf, 0,
Eigen::InnerStride<8> >(signal.data(), 1+((signal.size()-1)/8)).eval();
cout << endl << "Decimated:" << endl << decimatedSignal.transpose() << endl;
return 0;
}
outputs
Original signal:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
Decimated:
0 8 16 24 32 40 48 56
which I think is exactly what you want.
I have defined a Lsdb class with a function and parameters as below.
47 AdjacencyData
48 getAdjacentNode(const std::string routerName, const std::string adjacentNodeName);
49
50 private:
51 std::vector<AdjacencyData> m_AdjacencyList;
52 std::map<std::string, std::vector<AdjacencyData>()> m_Lsdb;
In the implementation of the method, I have below code.
43 Lsdb::getAdjacentNode(const std::string routerName, const std::string nodeName)
44 {
45
46 AdjacencyData nodeData;
47
48 // Get the adjacency list for given router.
49 std::map<std::string, std::vector<AdjacencyData>()>::iterator itr = m_Lsdb.find(routerName);
50 if (itr != m_Lsdb.end())
51 {
52 // Get the specific node data from list.
53 std::vector<AdjacencyData> nodeList = itr->second;
54
55 std::vector<AdjacencyData>::iterator listItr = nodeList.begin();
56 for(; listItr != nodeList.end(); listItr++)
57 {
58 nodeData = *listItr;
59 if (nodeData.getRouterName().compare(nodeName))
60 {
61 return nodeData;
62 }
63 }
64 }
65
66 return nodeData;
67 }
On compiling, I am getting the following error. Can someone please help understand what is the problem with this code?
In file included from /usr/include/c++/4.6/bits/stl_algobase.h:65:0,
from /usr/include/c++/4.6/bits/char_traits.h:41,
from /usr/include/c++/4.6/ios:41,
from /usr/include/c++/4.6/ostream:40,
from /usr/include/c++/4.6/iostream:40,
from ./ns3/assert.h:48,
from ../src/lsdb.cc:22:
/usr/include/c++/4.6/bits/stl_pair.h: In instantiation of ‘std::pair<const std::string, std::vector<AdjacencyData>()>’:
../src/lsdb.cc:50:25: instantiated from here
/usr/include/c++/4.6/bits/stl_pair.h:93:11: error: field ‘std::pair<const std::string, std::vector<AdjacencyData>()>::second’ invalidly declared function type
../src/lsdb.cc: In member function ‘AdjacencyData Lsdb::getAdjacentNode(std::string, std::string)’:
../src/lsdb.cc:53:48: error: conversion from ‘std::vector<AdjacencyData> (*)()’ to non-scalar type ‘std::vector<AdjacencyData>’ requested
you error is in this line:
std::map<std::string, std::vector<AdjacencyData>()>::iterator itr = m_Lsdb.find(routerName);
you are putting std::vector<AdjacencyData>(), which is a function, as the 2nd type of std::map, you should use std::vector<AdjacencyData>.