我有一个作业需要我计算每个单词的频率。从A-Z开始,长度为1-1000。
输出取决于字符的频率及其ASCII值。如果有两个具有相同的频率,则将打印具有较小ASCII值的字符。
如果输入为YVPDF,则输出为68 1 70 1 86 1 89 1
。
#include <iostream>
#include<algorithm>
#include<cstdlib>
#include<string>
using namespace std;
int i, j, k,temp;
int b[26] = { 0 };
int index[26] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
,17,18,19,20,21,22,23,24,25 };
void fillFrequency(string str1, int freqcount[])
{
for (string::size_type i = 0; i < str1.size(); i++)
{
++(freqcount[str1[i] - 'A']);
}
}
int main()
{
string a;
getline(cin, a, '\n');
fillFrequency(a, b);
for (j = 0; j < 26; j++)
{
for (k = j + 1; k < 26; k++)
{
int temp;
if (b[index[j]] < b[index[k]])
{
temp = index[j];
index[j] = index[k];
index[k] = temp;
}
}
}
for (i = 0; i < 26; ++i)
{
if (b[index[i]] >0)
{
cout << index[i] + 'A' << " " << b[index[i]] << endl;
}
}
system("pause");
return 0;
}
最终结果是正确的。 对于YVPDF 我有
68 1
70 1
80 1
86 1
89 1
如何提高效率? 我尝试使用sort()并创建了一个compare函数,但是它不起作用。
bool compare(int i,int j)
{
return b[index[i]] > b[index[j]];
}
它没有按照我想要的方式排序。
答案 0 :(得分:0)
如果输入小写字母,则会有一个UB,因为它们的代码不是大写,并且在数组中只保留了26个位置
该行返回数组的大小
int len = sizeof(b) / sizeof(*b);
只用它推入向量吗?向量可以从数组构造。
您的结果不可复制,输出状态如下:
YVPDF
21 1
13 1
0 1
7 1
2 1
仍然不正确,因为那不是ASCII码,而是字母索引吗?如果您希望输出中包含ascii代码,则可以将'A'
添加到index[i]
。
86 1
78 1
65 1
72 1
67 1
还是要走吗?
频率计数后的b:0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0
排序前的索引:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
排序后的索引:24 3 5 21 15 13 25 23 22 20 19 18 17 16 14 0 12 11 10 9 8 7 6 4 2 1
您的方法出了点问题,这种排序不能给您想要的结果。实际上是罪魁祸首:
if (data[i] > 0)
您的data
未排序,它仍然与b
数组的顺序匹配,并且您在打印错误的索引。我已经将它们加粗了。实际上,如果删除排序,您将在此行中获得正确的输出:
cout << index[i]+'A' << " " << data[i] << endl;
结果
68 1
70 1
80 1
86 1
89 1
这当然不是排序的,所以您应该为策略做其他事情。例如。使用std :: pair向量存储频率数据。这样的排序将涉及lambda,该lambda会比较对应于频率的对成员,但两个值将同时交换。