【发布时间】:2015-07-17 02:48:40
【问题描述】:
我正在尝试用c++制作这个频率表,我的代码如下。
#include <iostream>
#include <iomanip>
#include <string>
#include <algorithm>
#include <map>
#include <vector>
#include <cassert>
using namespace std;
typedef std::pair<std::string, int> mypair;
struct IntCmp {
bool operator()(const mypair &lhs, const mypair &rhs) {
return lhs.second < rhs.second;
}
};
string removeSpaces(string input) {
input.erase(std::remove(input.begin(),input.end(),' '),input.end());
input.erase(std::remove(input.begin(), input.end(), '\t'), input.end());
input.erase(std::remove(input.begin(), input.end(), '.'), input.end());
return input;
}
void printmap(const std::map<std::string,int> &mymap, int size) {
std::vector<mypair> myvec(mymap.begin(), mymap.end());
assert(myvec.size() >= size);
std::partial_sort(myvec.begin(), myvec.begin() + size, myvec.end(), IntCmp());
for(int i = size; i --> 0;) {
std::cout << myvec[i].first << " " << myvec[i].second << "\n";
}
}
int main() {
string str;
cout << "Enter text:\n";
cin >> str;
cout << "Frequencies:\n";
str = "do be do bo.";
str = removeSpaces(str);
int size = str.size();
string *array = new string[size];
for(int i = 0; i < size; ++i) {
array[i] = str[i];
}
sort(array, array+size);
map<int, string> mymap;
for(int i = 0; i < size; ++i) {
mymap[i] = array[i];
}
map<string, int> freq;
for(int i = 0; i < size; ++i) {
if(freq.count(mymap[i]) == 0) {
//Not found
freq[mymap[i]] = 1;
}
else {
//Found
freq.at(mymap[i]) = freq.at(mymap[i]) + 1;
}
}
int mapsize = freq.size();
printmap(freq, mapsize);
}
当我使用do be do bo. 给出的str 运行代码时,输出如下
o 3
d 2
b 2
e 1
这是我的思考过程。
我将输入str 放入一个数组中,然后按字母顺序对该数组进行排序,然后将该数组放入映射mymap 中。然后,我取mymap 并获取每个字符串的频率并将字母作为键并将频率作为映射freq 中的值。然后,我使用printmap() 函数按值降序对地图进行排序。
但是,当我这样做时,键是随机排序的。因此,例如,在上面显示的字符串中,b 2 在d 2 之后打印出来,即使当我将freq 映射给printmap() 函数时它们是有序的。
本质上,我正在寻找一种方法,在 printmap() 函数中按值,然后按键对地图进行排序,因此结果按降序值和字母键打印出来。
do be do bo. 的期望结果如下:
o 3
b 2
d 2
e 1
谢谢。
【问题讨论】: