упорядочение карт от наибольших к наименьшим на основе их сохраненных значений в C ++

0

Хорошо, поэтому у меня есть 2 вопроса, но я думаю, что они легко доступны опытному программисту и несколько похожи. Если это вас беспокоит, просто помогите мне с одним вопросом, а не другим. В основном у меня есть карта (char, int), которая связывает количество символов, появляющихся в строке со значением int. Проблема, с которой я сталкиваюсь, заключается в том, что я не могу понять, как распечатать связанные значения из наиболее распространенных в меньшей степени. Например, если я набираю aabbbcddddd. Я получаю: 2 b: 3 c: 1 d: 5. Но я пытаюсь получить d: 5 b: 3 a: 2 c: 1. Надеюсь, я объясню это хорошо...

Второй вопрос. Мне также было интересно, как можно сделать карты, которые делают то же самое, что и выше, но с серией букв ИЛИ чисел. Пример: со строкой: "aabbb001c1 ddd"..."aabbb", "c" и "ddd" будут все отдельными словами. "001" и "1" будут номерами, однако они не будут равны. Я попытался использовать две отдельные карты (string, int) для этого (один для слов один для чисел), с серией, отрезанной, когда появился персонаж, который не имеет своего "типа", но ничего не работает. Техника или любой совет были бы хороши. Вот код, который у меня есть до сих пор.

#include <iostream>
#include <string>
#include <sstream>
#include <map>
#include <stdio.h>
#include <ctype.h>
#include <algorithm>

using namespace std;

int main()
{

    string word;

    getline(cin, word);

    map<char,int> charCount;
    map<string, int> strCount;
    map<string, int> numCount;

    //turning all characters to lower case
    transform(word.begin(), word.end(), word.begin(), ::tolower);

    //for loop to count recurring characters
    for (unsigned int i=0; i<word.size(); i++){
        charCount[word[i]]++;
    }

    //Having trouble here. This is where i'm doing my series of words & numbers
    string temp;
    string temp2;

    for (unsigned int j=0; j<word.size(); j++){
        if (isalpha(word[j]))
            temp = temp + word[j];
        else{
          wordCount[temp]++;
          temp2.clear();
        }
        if (isdigit(word[j]))
            temp2 = temp2 + word[j];
        else{
            numCount[temp2]++;
            temp2.clear();
        }

    }


    //print out chars
    for (map<char, int>::iterator it = charCount.begin(); it != charCount.end(); ++it)
        cout << it->first << ": " << it->second << endl;

    //print out words
    for (map<string, int>::iterator it = wordCount.begin(); it != wordCount.end(); ++it)
        cout << it->first << ": " << it->second <<endl;

    //print out numbers
    for (map<string, int>::iterator it = numCount.begin(); it != numCount.end(); ++it)
      cout << it->first << ": " << it->second << endl;

    return 0;
}
Теги:
map

1 ответ

0
Лучший ответ

std::map сортируется по ключу, а не по значению, и ни механизм сортировки, ни значения ключей не могут быть изменены после создания карты.

Таким образом, ваша карта уже отсортирована по char, но вы хотите отобразить ее значение - другой порядок сортировки.

Простейшей задачей было бы построить std::multimap где ключ - это число вхождений (значение из исходной карты), а значение - символ. Использование multimap в отличие от map позволяет вам иметь несколько символов с одинаковым количеством вхождений. Когда вы будете готовы отображать значения, скопируйте ключи и значения map в multimap а затем отобразите содержимое multimap.

Вот пример (Live Demo):

#include <iostream>
#include <iomanip>
#include <map>
#include <string>
#include <utility>
using namespace std;

int main() {
    const string data = "foofaaster";

    // populate the map
    map <char, int> chars;
    for (auto c = data.begin(); c != data.end(); ++c)
        chars [*c]++;

    // Now display the occurances
    cout << "Original data: '" << data << "'" << endl;
    multimap <int, char, greater <int>> counts;
    for (auto c = chars.begin(); c != chars.end(); ++c)
        counts.insert (make_pair (c->second, c->first));
    cout << "Character counts:" << endl;
    for (auto it = counts.begin(); it != counts.end(); ++it)
        cout << "\t" << it->first << ": '" << it->second << "'" << endl;


    return 0;
}

Что касается второго вопроса, если ваши ключи карты статичны и там одно значение для каждого ключа, то вы можете использовать std::map <std::string, int>. В противном случае, если подэлементы ключа будут иметь свои собственные значения, вы можете рассмотреть другую структуру данных, более подходящую для задачи, такую как trie.

  • 0
    Это полезно Но, черт возьми, я надеялся, что решение будет немного проще, чем это. Я собираюсь прочитать в мультикартах, чтобы полностью понять их, спасибо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню