Home > Software engineering >  how to sort a vector of string and integer pairs by the second key value which is integer?
how to sort a vector of string and integer pairs by the second key value which is integer?

Time:12-02

I have a vector storing the most frequent words in a file. Initially the values was stored in a map of strings and integers but then I copied the map into the vector I thought it would be easier to sort. Then I realized that the std sort() function sorts the vector by the first key (string in this case). But I want to sort it such that the most used words at the top and the least used at the bottom.

#include <iostream>
#include <fstream>
#include <map>
#include <algorithm>
#include <vector>
#include <iterator>

using namespace std;

int main(){
  
  fstream fs; 
  fs.open("/Users/brah79/Downloads/skola/c  /codeTest/test.txt");
  string word; 
  map <string, int> list; 
  while(fs >> word){
    if(list.find(word) != list.end()){
      list[word]  ; 
    }
    else{
      list[word] = 1; 
    }
  }

  vector <pair <string, int> > vector(list.begin(), list.end()); 

  sort(vector.begin(), vector.end() greater<int>()); 
  for(int i = 0; i < vector.size(); i  ){
    if(vector[i].second == 1){
      cout << vector[i].first << " is repeated " << vector[i].second << " time" << endl; 
    }
    else{
      cout << vector[i].first << " is repeated " << vector[i].second << " times" << endl;
    }
  }



  return 0; 
}

CodePudding user response:

First of all, as mentioned in a comment, this is too complicated:

if(list.find(word) != list.end()){
  list[word]  ; 
}
else{
  list[word] = 1; 
}

It looks up the key word twice, when it has to be looked up only once, because this does the same:

 list[word]  ;

operator[] already does add a default constructed element if none exists in the map.

Then I see no reason to store the item you want to have sorted as first rather than second:

 std::vector<std::pair<int,std::string> v; // dont use same name for type and variable

 for (const auto& e : list) {  // with using namespace std there is no way to distinguish this from std::list  :(
     v.emplace_back( e.second , e.first );
 }

Now you can use std::sort with std::greater. Alternatively, keep the pairs as they are and write a custom comparator that compares std::pair(second,first).

  • Related