C ++: sorting characters by line by frequency and then alphabetically

Given a string, I try to count the occurrence of each letter in a string and then sort its frequency from highest to lowest. Then, for letters with the same number of occurrences, I have to sort them alphabetically.

So here is what I have been able to do so far:

  • an int array of size 26 was created, corresponding to 26 letters of the alphabet with individual values ​​representing the number of times it appeared in the sentence
  • pushes the contents of this array into a vector pair v, int and char. (int for frequency and char for the actual letter)
  • sorted this pair of vectors using std :: sort (v.begin (), v.end ());

When displaying the frequency reference, I simply used the for loop, starting from the last index, to display the result from the highest to the lowest. However, I am having problems with those letters that have the same frequencies, because I need them in alphabetical order. I tried using a nested loop loop with an inner loop starting at the lowest index and using a conditional statement to check if its frequency matches the outer loop. This worked, but my problem is that I cannot figure out how to manage these loops to avoid redundant results. To understand what I'm saying, see this example:

Output Example:

Enter a string: hello world

Pushing the array into a vector pair v:
d = 1
e = 1
h = 1
l = 3
o = 2
r = 1
w = 1


Sorted first according to frequency then alphabetically:
l = 3
o = 2
d = 1
e = 1
h = 1
r = 1
w = 1
d = 1
e = 1
h = 1
r = 1
d = 1
e = 1
h = 1
d = 1
e = 1
d = 1
Press any key to continue . . .

As you can see, it would be nice if it were not for the redundant outputs caused by the wrong for the loops.

, , , ++.

, :

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    cout<<"Enter a string: ";
    string input;
    getline(cin, input);

    int letters[26]= {0};

    for (int x = 0; x < input.length(); x++) {
        if (isalpha(input[x])) {
            int c = tolower(input[x] - 'a');
            letters[c]++;
        }
    }

    cout<<"\nPushing the array into a vector pair v: \n";
    vector<pair<int, char> > v;

    for (int x = 0; x < 26; x++) {
        if (letters[x] > 0) {
            char c = x + 'a';
            cout << c << " = " << letters[x] << "\n";
            v.push_back(std::make_pair(letters[x], c));
        }
    }

    //sort the vector pair
    std::sort(v.begin(), v.end());

    //Need help here!//
    cout<<"\n\nSorted first according to frequency then alphabetically: \n";
    for (int x = v.size() - 1 ; x >= 0; x--) {
        for (int y = 0; y < x; y++) {
            if (v[x].first == v[y].first) {
                cout << v[y].second<< " = " << v[y].first<<endl;
            }
        }
        cout << v[x].second<< " = " << v[x].first<<endl;
    }

    system("pause");
    return 0;
}

!!

* UPDATE: * !! , StackOverflow, . , - , :

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

struct Letters
{
    Letters() : freq(0){}
    Letters(char letter,int freq) {
        this->freq = freq;
        this->letter = letter;
    }
    char letter;
    int freq;
};

bool Greater(const Letters& a, const Letters& b)
{
    if(a.freq == b.freq)
        return a.letter < b.letter;

    return a.freq > b.freq;
}

int main () {

    cout<<"Enter a string: ";
    string input;
    getline(cin, input);

    vector<Letters> count;
    int letters[26]= {0};

    for (int x = 0; x < input.length(); x++) {
        if (isalpha(input[x])) {
            int c = tolower(input[x] - 'a');
            letters[c]++;
        }
    }

    for (int x = 0; x < 26; x++) {
        if (letters[x] > 0) {
            char c = x + 'a';
            count.push_back(Letters(c, letters[x]));
        }
    }

    cout<<"\nUnsorted list..\n";
    for (int x = 0 ; x < count.size(); x++) {
        cout<<count[x].letter<< " = "<< count[x].freq<<"\n";
    }

    std::sort(count.begin(),count.end(),Greater);

    cout<<"\nSorted list according to frequency then alphabetically..\n";
    for (int x = 0 ; x < count.size(); x++) {
        cout<<count[x].letter<< " = "<< count[x].freq<<"\n";
    }

    system("pause");
    return 0;
}

:

Enter a string: hello world

Unsorted list..
d = 1
e = 1
h = 1
l = 3
o = 2
r = 1
w = 1

Sorted list according to frequency then alphabetically..
l = 3
o = 2
d = 1
e = 1
h = 1
r = 1
w = 1
Press any key to continue . . .

@Oli Charlesworth : .

, ? , .:)

!!

+4
2

, , , . , , :

struct sort_helper {
   bool operator()(std::pair<int,char> lhs, std::pair<int,char> rhs) const{
     return std::make_pair(-lhs.first,lhs.second)<std::make_pair(-rhs.first,rhs.second);
   }
};
std::sort(vec.begin(),vec.end(),sort_helper());
+3

:

  • , :

    std::unordered_map<char,unsigned int> count;
    
    for( char character : string )
        count[character]++;
    
  • :

    std::sort( std::begin( string ) , std::end( begin ) , 
               [&]( char lhs , char rhs )
               {
                   return count[lhs] < count[rhs];
               }
             ); 
    

- , ideone.

+5

All Articles