Ordering in unordered_map in C++

Viewed 196

So I have an array as :

arr[] = {5, 2,4,2,3,5,1};

How can I insert them in this order with the number of times they occur in unordered_map?

#include<bits/stdc++.h>

using namespace std;

void three_freq(int arr[], int n){
    unordered_map<int, int> m;

    for(int i=0;i<n;i++){
        m[arr[i]]++;
    }

    for(auto itr = m.begin(); itr != m.end(); itr++){
        cout<<itr->first<<":"<<itr->second<<"\n";
    }

}

int main(){
    int arr[] = {5, 2,4,2,3,5,1};
    int n = sizeof(arr)/ sizeof(arr[0]);
    three_freq(arr, n);
    return 0;
}

Using the code above I am getting output as :

1:1
3:1
4:1
5:2
2:2

But I want the output to be in same order as the element occur in array. Example:

5:2
2:2
4:1
3:1
1:1
3 Answers

If you don't care about efficiency (that much), then you can just change the for loop which is printing the output.

for(int i=0; m.size(); i++) {
   auto it = m.find(arr[i]); 
   if (it != m.end()) {
      cout<<arr[i]<<":"<<it->second<<"\n";
      m.erase(it);
    }
} 

You need unordered_map to do the counting efficiently, so keep that.

When printing out according to the order in another container, it makes sense to simply iterate over that other container for your output loop.

(Note that this is a completely separate operation, so it could have been a different function.)

// loop over the original array (recommend std::vector)
// exit early if done (stole from fadedreamz)
for (int index = 0; !m.empty(); ++index) {
    int number = arr[index];
    // check to see if we need to print this number
    // use contains if you have c++20
    if (m.count(number)) {
        std::cout << number << ":" << m[number] << std::endl;
        m.erase(number); // print only once by deleting the entry
    }
}

The quite efficient way is traversing the original array and resetting the counters after print.

for (int i = 0; i < n; ++i) {
  if (m[a[i]]) != 0) {
    std::cout <<arr[i] << ":" << m[a[i]] << std::endl;
    m[a[i]] = 0;
  }
}
Related