How to sum up values of occuring chars from a string, make them pairs and sort them in ascending order?

Viewed 192

My task is to write a function that gets a vector of strings as an argument, and returns a vector of pair<char,int> containing pairs representing characters and their frequency (how much times the letter has appeared) summed up from all strings passed in vector as an argument of the function. It should also be sorted in ascending order.

The code below is my approach on how to do it. So far I'm only able to count how many times the character occured in every string, but I'm not able to sum all of the occuring letters to be the one pair.

#include <iostream>
#include <vector>
#include <utility>
#include <string>

using namespace std;

bool isEqual(const pair<char, int> &element) {
    return element.first;
}

vector<pair<char, int>> all_occurrences(vector<string> vec) {

    vector<pair<char, int>> sorted_vec;
    vector<pair<char, int>> final_vec;

    char c;
    int count_chars = 0;
    string element;
    vector<char> check_chars = {' '};
    bool char_found = false;

    for (int i = 0; i < vec.size(); i++) {

        element = vec[i];

        for (int j = 0; j < element.length(); j++) {

            c = element.at(j);

            for (int k = 0; k < check_chars.size(); ++k) {
                if (c == check_chars[k]) {
                    char_found = true;
                    break;
                }
            }

            if (!char_found) {
                check_chars.push_back(c);
                count_chars = count(element.begin(), element.end(), c);
                sorted_vec.push_back(make_pair(c, count_chars));
            }

            char_found = false;

        }
        check_chars = {' '};
    }

    vector<pair<char, int>>::iterator it;

    for (int i = 0; i < sorted_vec.size(); ++i) {

        it = find_if(sorted_vec.begin(), sorted_vec.end(), isEqual);
        cout << it << endl;

    }


    return sorted_vec;
}

void print_vector(vector<pair<char, int>> pair_vector) {

    cout << "---" << endl;

    for (int i = 0; i < pair_vector.size(); i++) {
        cout << pair_vector[i].first << ',' << pair_vector[i].second << endl;
    }

    cout << "---" << endl;

}


int main() {

    vector<string> string_vector = {"ala", "ma", "kota"};
    print_vector(all_occurrences(string_vector));
    return 0;
}
1 Answers

First you can calculate all the frequency counts with a std::map:

std::map<char,int> m;
for(auto c : vec | std::views::join)  // for every char in all strings
    m[c]++;

Then you can copy this map into a vector as needed:

vector<pair<char, int>> res;
std::ranges::copy(m, std::back_inserter(res));        

And finally you can sort the vector in ascending order of the frequency counts:

std::ranges::sort(res, std::less{}, &std::pair<char, int>::second);

Here's a demo.


Pre C++20, you can write the above code like this:

Construct a frequency count:

std::map<char,int> m;
for (auto const &s : vec)  // for every string
    for(auto c : s)        // for every character
        m[c]++;            // add to the frequency count  

Copy into a vector:

vector<pair<char, int>> res;
std::copy(m.begin(), m.end(), std::back_inserter(res));        

And sort it:

std::sort(res.begin(), res.end(), [](auto a, auto b) {
    return a.second < b.second;
});

Here's a demo.

Related