#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;
}
Related
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)
i try to implement freq unordered map but it has weird behavior , why when i use unordered_map it gives me keys with negative numbers and when i use map it will give my the correct keys values.
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int maxOperations(vector<int>& nums, int k) {
unordered_map <int,int> mp;
for(auto i:nums){
mp[i]++;
}
int count=0;
// for(auto i:mp)
// cout << i.first << " " << i.second << endl;
for(auto i:mp){
int target= k-i.first;
cout << i.first << " " << i.second << " "<< mp[target] << endl;
if(i.second>0 && mp[target]>0){
if(i.first!=target){
count += min(i.second,mp[target]);
mp[target]=0;
//i.second=0;
mp[i.first]=0;
}else
{
cout << count << endl;
count += floor(i.second/2);
mp[target]=0;
}
}
}
return count;}
int main()
{
vector<int> vec= {29,26,81,70,75,4,48,38,22,10,51,62,17,50,7,7,24,61,54,44,30,29,66,83,6,45,24,49,42,31,10,6,88,48,34,10,54,56,80,41,19};
int k =12 ;
cout << maxOperations(vec,k);
return 0;
}
When you use an ordered map, you traverse the keys in order. Thus, target is never negative. When you traverse an unordered map, it is unordered. Therefore, target is sometimes negative.
If the negative values are not correct, then you need to traverse the map in order and so you should not use an unordered map.
Another problem with traversing out of order is that when modifying the map while traversing it, you will create entries that may or may not be included in your traversal. That will cause unpredictable behavior. You may prefer to create new entries in a separate container and merge them into the original container only when you're finished traversing.
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}
I have made this code to store the position of each bit 1 entered in a binary sequence. The output of the program is not what it is desired. The output I get for 10100 is 0x7fff9109be00. Here is the code:
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
bitset <5> inpSeq;
int x = 0;
int xorArray[x];
unsigned int i;
cout << "Enter a 5-bit sequence: \n";
cin >> inpSeq;
for ( i = 0; i < inpSeq.size(); i++)
{
if ( inpSeq[i] == 1 )
{
x = x+1;
xorArray[x] = i;
}
}
cout << xorArray << "\n";
}
Update for clarity: What I had in mind was that 'cout << xorArray' will print bit 1's positions.
cout << xorArray << "\n";
This does not print the elements of xorArray; it prints its address.
You must iterate ("loop over") it:
for (auto x : xorArray)
cout << x << ' ';
cout << '\n';
Your other problem is that you're trying to use a variable-length array, which does not exist in C++. Use a vector instead.
Now it gives you your desired output:
#include <iostream>
#include <bitset>
#include <vector>
using namespace std;
int main()
{
bitset<5> inpSeq("10111");
std::vector<int> xorArray;
for (unsigned int i = 0; i < inpSeq.size(); i++) {
if (inpSeq[i] == 1)
xorArray.push_back(i);
}
for (auto x : xorArray)
cout << x << ' ';
cout << '\n';
}
If you're not using C++11 for whatever reason, you can perform that final loop the traditional way:
for (std::vector<int>::const_iterator it = xorArray.begin(),
end = xorArray.end(),
it != end; ++it) {
cout << *it << ' ';
}
Or the naive way:
for (unsigned int i = 0; i < xorArray.size(); i++)
cout << xorArray[i] << ' ';
I am a little unclear on exactly what you are trying to achieve, but I think the following might help.
#include <iostream>
#include <bitset>
#include <list>
using namespace std;
int main() {
bitset<5> inpSeq;
unsigned int i;
list<int> xorList;
cout << "Enter a 5-bit sequence: \n";
cin >> inpSeq;
for (i = 0; i < inpSeq.size(); ++i) {
if (inpSeq[i] == 1) {
xorList.push_back(i);
}
}
for (list<int>::iterator list_iter = xorList.begin();
list_iter != xorList.end(); list_iter++)
{
cout << *list_iter << endl;
}
return 0;
}
The reason why I am using a list is because you mentioned wanting to store the positions of the 1 bit. The list is being used as the container for those positions, in case you need them in another point in the program.
One of the problems with the original code was that you assigned variable 'x' the value 0. When you declared xorArray[x], that meant you were essentially creating an array of length 0. This is incorrect syntax. It looks like you actually were trying to dynamically allocate the size of the array at runtime. That requires a different syntax and usage of pointers. The list allows you to grow the data structure for each 1 bit that you encounter.
Also, you cannot print an array's values by using
cout << xorArray << endl
That will print the memory address of the first element in the array, so, xorArray[0]. Whenever you want to print the values of a data structure such as a list or array, you need to iterate across the structure and print the values one by one. That is the purpose of the second for() loop in the above code.
Lastly, the values stored are in accordance with the 0 index. If you want positions that start with 1, you'll have to use
xorList.push_back(i+1);
Hope this helps!
I am using a C++ STL set with a custom comparator to store an Edge data structure as shown below. I defined the Edge to be essentially a key-value pair. Index is the key and I want to iterate through the collection by value (maxlength) from largest to smallest. At any given time, I usually only care about the edges with the 3 largest values. There will only be a relatively small number of edges in the collection ranging from around 7 to 64. When I insert an edge, the values of the two adjacent edges will need to be adjusted. To do this, I will add the new edge to the set, then remove the two adjacent edges and re-add them with their new values. Can anyone share a more efficient data structure for this purpose?
#include <iostream>
#include <iomanip>
#include <sstream>
#include <set>
using namespace std;
struct Edge {
int maxlength;
int index;
Edge(int index, int maxlength) {
this->maxlength = maxlength;
this->index = index;
}
bool operator<(Edge other) const {
return maxlength < other.maxlength;
}
};
void run() {
set<Edge> edges;
edges.insert(Edge(25, 3));
edges.insert(Edge(21, 4));
edges.insert(Edge(28, 2));
cout << "First Edge: " << edges.begin()->maxlength << endl;
edges.erase(Edge(28, 2));
cout << "First Edge: " << edges.begin()->maxlength << endl;
edges.insert(Edge(39, 1));
cout << "First Edge: " << edges.begin()->maxlength << endl;
cout << "Last Edge: " << (--edges.end())->maxlength << endl;
}
int main() {
run();
return 1;
}