Хорошо, поэтому у меня есть 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;
}
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.