Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am currently doing a research about implement a C++ programe by using Q-learning algorithm to help the agent get the reward.
I am trying to use the Hashtable to store my states and Actions.
I am not familiar with the C++ programming...
What i am trying to do is like using hashtable to store the Arrays.
but i can not find the right way to store it... the hashtable said it is an error type of the array.
using namespace std;
int state[2] = {0,0};
unordered_map<string, int> hashtable;
hashtable.emplace("State1", state);
cout << "the State of State1 is :" << hashtable["State1"] << endl; cin.get();
Error C2664 'std::pair<const _Kty,_Ty>::pair(std::pair<const _Kty,_Ty> &&)': cannot convert argument 2 from 'int [2]' to 'const int &' myproject c:\program files (x86)\microsoft visual studio
14.0\vc\include\xmemory0 737
Does C++ HashTable can Store an Array as Key and Value?
If it Doesn't is there any way to store an Array in a table? which like the Python dictionary function....
Thanks!
there are some tips of unordered_map which can help u.
#include <iostream>
#include <unordered_map>
#include <string>
#include <vector>
using namespace std;
int main() {
// constructor
unordered_map<string, int> hashTable = {
{"a", 123},
{"b", 456},
{"c", 789}
};
// update
hashTable["a"] = 1;
// add new entry
hashTable["d"] = 2;
hashTable.insert({"e", 111});
// Iterate and print keys and values of unordered_map
for (const auto& n : hashTable )
cout << "Key: " << n.first << "\tValue: " << n.second << endl;
// Output values by key
cout << "The value of d is :" << hashTable["d"] << endl;
// init vector
vector<int> states{1,2,3,4,5,6,7};
states.push_back(8);
// add vector into unordered_map
unordered_map<string, vector<int>> ht;
ht["state1"] = states;
ht.insert({"c", vector<int>{1,1,1,1}});
cout << "Values which key is 'c' in ht" << endl;
for(auto& v : ht["c"])
cout << v << "\t";
cout << endl;
/*
* put array into unordered_map
*/
int state1[3] = {0, 1, 2};
int state2[2] = {3, 4};
int state3[4] = {5, 6, 7, 8};
// declare map to store int pointer value
unordered_map<string, int*> u_map;
// add into unordered_map
u_map["a"] = state1;
u_map["b"] = state2;
u_map.insert({"c", state3});
// update
u_map["b"] = state3;
// get pointer of array
auto s1 = u_map["a"];
int* s2 = u_map["b"];
// accesses val in array
cout << "Value of key a is: "<< s2[0] << endl;
size_t size = sizeof(s1)/sizeof(s1[0]);
for (int i = 0; i <= size ; ++i) {
cout << "val " << i << " is: "<< s1[i] << endl;
}
return 0;
}
output:
Key: d Value: 2
Key: b Value: 456
Key: c Value: 789
Key: a Value: 1
The value of d is :2
Value of key a is: 5
val 0 is: 0
val 1 is: 1
val 2 is: 2
update:
fix use of class template 'vector' requires template arguments
update for adding array into map
if i got this right you want to have "unordered_map< string, std::array>" not "unordered_map< string, int>". so the your code should look something like this:
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;
int main() {
unordered_map<string, std::array<int,2>> hashTable = {
{"State1", {1,10}},
{"State2", {2,20}},
{"State3", {3,30}},
};
for (const auto& n : hashTable )
cout << "Key: " << n.first << "\tValue: {" << n.second[0] << ", " << n.second[1] << "}" << endl;
return 0;
}
The output will be:
Key: State3 Value: {3, 30}
Key: State1 Value: {1, 10}
Key: State2 Value: {2, 20}
Related
I'm having a struct with an array which is static and want to access the data in that array. Tried to use the new C++11 for loops and also do it without the for loop and just print array[1]. See the second cout in the main function.
I already know that the problem have to do something with the fact that the array in the struct tCalcAngularEstimationFromComplexData_32 is adjusted as a pointer type. Therefore I tried to use for (const auto &arr : &test_data_1) but wasn't able to solve it.
Thanks.
typedef struct tComplex_R {
float real;
float imag;
}tComplex_R;
typedef struct tOutputVRx_R {
float range;
float vel;
tComplex_R AmpLinRx[1];
} tOutputVRx_R;
typedef struct tCalcAngularEstimationFromComplexData_32{
int antennas_azimuth;
int antennas_elevation;
tOutputVRx_R dataset1[32]; //Range Velocity and Complex Data for 32 Antennas
} tCalcAngularEstimationFromComplexData_32;
static tCalcAngularEstimationFromComplexData_32 tCalcAngEstComplexData_dataset_1 = {
5, 90,
{{1, 3, {10, 15}},
{2, 4, {11, 16}}
}
};
int main(){
tCalcAngularEstimationFromComplexData_32 test_data_1 = tCalcAngEstComplexData_dataset_1;
cout << "Range 1: " << test_data_1.dataset1->range << endl;
cout << "Range 2: " << test_data_1.dataset1[1]->range << endl; //Not working
for (const auto &arr : test_data_1) {
cout << "Range: " << arr.dataset1->range << endl;
}
}
Range-based for loops need to have access to the bounds of what you're iterating.
As noted on the relevant cppreference page, there are three ways:
It is an array of known size (which is the case for your dataset1 member)
my_struct::begin() and my_struct::end() are defined
begin(my_struct&) and end(my_struct&) are defined
As for this line:
cout << "Range 2: " << test_data_1.dataset1[1]->range << endl; //Not working
It is because dataset1[1] is not a pointer but a reference, so you don't use -> but . instead.
See a working example on godbolt
I am trying to use the unordered_map in C++, such that, for the key I have a string, while for the value there is an array of floats.
std::unordered_map<std::string, std::array<float, 3>> umap;
But, I am not sure how to access the array of values. I know to access the elements, an iterator is an option, but how specifically elements of an array can be accessed?
I am trying to assign these array values to different array (std::array mapArrayVal)
I tried using
for (auto i = umap.begin(); i != umap.end(); i++)
{
std::array<float, 3> mapArrayVal = (i->second.first, i->second.second,
i>second.third);
}
is the correct way? Any help is appreciated, TIA!
This example shows you how to do it with some comments to help you on your way :
#include <array>
#include <iostream>
#include <string>
#include <unordered_map>
int main()
{
// a map consists of key,value pairs in your case
// the key will have a type of std::string
// the value will be an std::array (with three entries)
std::unordered_map<std::string, std::array<float, 3>> umap{
{"key1", {1.0,2.0,3.0}},
{"key2", {4.0,5.0,6.0}}
};
// iterate over all entries using an explicitly type it
// normally you would type auto i.o. std::unordered_map<std::string, std::array<float, 3>>::iterator
// but this shows all the types involved
for (std::unordered_map<std::string, std::array<float, 3>>::iterator it = umap.begin(); it != umap.end(); ++it)
{
// access key/values by iterator it->second will be the array
std::cout << "key = `" << it->first << "`, values : {" << (it->second)[0] << ", " << (it->second)[1] << ", " << (it->second)[2] << "}\n";
}
// however with c++ you could do it in a much more readable way
// combine range based for loop : https://en.cppreference.com/w/cpp/language/range-for
// with structured binding : https://en.cppreference.com/w/cpp/language/structured_binding
// the key_value_pair is const since you only want to observe it for printing
for (const auto& [key, values] : umap)
{
std::cout << "key = `" << key << "`, values : {" << values[0] << ", " << values[1] << ", " << values[2] << "}\n";
}
// use at(key) in map don't use operator[] it may insert an "empty" item in the map if something isn't found there!
auto& reference_to_array_in_map = umap.at("key1");
// this is how you make a copy of the array
std::array<float, 3> copied_values{ reference_to_array_in_map };
for (const float value : copied_values)
{
std::cout << value << " ";
}
std::cout << "\n";
return 0;
}
How can the unordered_set can hold both (0, 1) and (1, 0) if they have the same hash value?
#include <iostream>
#include <unordered_set>
#include <utility>
using namespace std;
struct PairHash
{
template <class T1, class T2>
size_t operator()(pair<T1, T2> const &p) const
{
size_t hash_first = hash<T1>{}(p.first);
size_t hash_second = hash<T2>{}(p.second);
size_t hash_combined = hash_first ^ hash_second;
cout << hash_first << ", " << hash_second << ", " << hash_combined << endl;
return hash_combined;
}
};
int main()
{
unordered_set<pair<int, int>, PairHash> map;
map.insert({0, 1});
map.insert({1, 0});
cout << map.size() << endl;
for (auto& entry : map) {
cout << entry.first << ", " << entry.second << endl;
}
return 0;
}
Output:
0, 1, 1
1, 0, 1
2
1, 0
0, 1
Link to onlinegdb.
unordered_set can hold one instance of any unique data-value; it is not limited to only holding data-values with unique hash-values. In particular, when two data-values are different (according to their == operator) but both hash to the same hash-value, the unordered_set will make arrangements to hold both of them regardless, usually at a slightly reduced efficiency (since any hash-based lookups for either of them will internally hash to a data structure that holds both of them, which the unordered_set's lookup-code will have to iterate over until it finds the one it is looking for)
#include<bits/stdc++.h>
using namespace std;
int main() {
map<int, int> nums_map;
cout << nums_map.count(0) << endl;
int a = nums_map[0];
cout << nums_map.count(0) << endl;
cout << nums_map[0];
return 0;
}
OUTPUT:
0
1
0
It makes no sense to me at least, why the line:
int a = nums_map[0];
is increasing the value of count by 1, also the nums_map.empty() = 0 at the same time.
Because std::map::operator[] works in a slightly weird way. From the documentation on std::map::operator[]:
Returns a reference to the value that is mapped to a key equivalent to key, performing an insertion if such key does not already exist.
So if the key doesn't exist, it creates a new pair. That's exactly what's happening here.
#include <iostream>
#include <map>
int main() {
using namespace std;
map<int, int> nums_map; // nums_map == {}
cout << nums_map.count(0) << endl; // 0, because the map is empty
int a = nums_map[0]; /* a new key/value pair of {0, 0} is
created and a is set to nums_map[0],
which is 0 */
cout << nums_map.count(0) << endl; // Since there is one key 0 now, this shows 1
cout << nums_map[0]; // As shown previously, nums_map[0] is 0
return 0;
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I have a vector of string including :- chemistry physics maths.
I want to access first character of each word ie c of chemistry p of physics and m of maths. How to do that?
You can output the first index element through this process.
I have made a 2D vector and applied a for loop so each row of the vector's first element is printed.
#include <iostream>
#include <vector>
int main()
{
std::vector<std::string> vec = {"chemistry", "maths", "physics"};
for(int i=0;i<vec.size();i++)
{
std::cout << vec[i][0];
}
return EXIT_SUCCESS;
}
You can also use a range based for loop
for (auto &i : vec)
std::cout << i[0] << " ";
The output will be
c m p
You can treat it like a 2D matrix of characters.
Given the vector of strings:
std::vector<std::string> vec = {"chemestry", "physics", "math"};
You can use a normal loop to access all first characters:
for (int i = 0; i < vec.size(); i++)
std::cout << vec[i][0] << " ";
Or a range based loop:
for (auto &str : vec)
std::cout << str[0] << " ";
Output:
c p m
I think this code should do the trick. If not then the Compiler is being a racist and doesn't like you that much. In that case you can just go-to your old buddy cpp.sh :D
String is a char Array and you can access it's contents from indexes like so
std::string str = "Hello";
std::cout << "First Index: " << str[0];
Output:-
H
Same goes for the vector as well
std::vector <char> str = "World!";
std::cout << "First Index: " << str[0];
Output:-
W
Now if you combine those two, it makes it a 2D Array so you have to access it like you access data from a 2D Array/Matrix.
std::vector <std::string> str = {"Hello", "World", "!"};
std::cout << "First Index Of Element 1: " << str[0][0] << std::endl
<< "First Index Of Element 2: " << str[1][0] << std::endl
<< "First Index Of Element 3: " << str[2][0] << std::endl;
Output:-
H
W
!
Program:-
#include <iostream>
#include <vector>
int main() {
std::vector <std::string> vec = {"chemistry", "physics", "math"};
for (int i=0; i < vec.size(); i++) { //-- size(); Function gives the size of a vector
std::cout << vec[i][0] << std::endl;
}
return 0;
}
Output:-
c
p
m
Press any key to continue...