编写一个程序,该程序将任意数量的文件名作为命令行参数,并计算出所有文件中出现的英文字母(A到Z)中每个字母的频率。忽略所有不属于基本英文字母的字符。您应该将相同字母的大写和小写视为相同。向用户报告每个字母的数量及其整体频率(占总字母的百分比)。您不必担心带有变音符号(例如变音符号)的字母或标准字母表中的其他变体。 (我建议使用矢量或地图来存储计数,而不是使用许多条件或切换。)
我有大部分想法,但是一旦我遍历文件的每个单独字符,我如何向相应的向量元素添加计数?这是我的尝试,但它充满了错误。
#include <iostream>
#include <cmath>
#include <vector>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;
int main(int argc, char* argv[]){
double total_letters = 0.0;
vector<double> counts[26]={};
if (argc == 1) {
cout << "You did not enter any command line arguments!" << endl;
return 0;
}
for(int i = 1; i <= argc - 1; i++){
ifstream ifs(argv[i]);
if (!ifs.is_open()){
cout << "Error: file could not be opened." << endl;
return 0;
}
string words = "";
ifs >> words;
for(int i = 0; i < words.size()-1; i++){
if((tolower(words[i]) >= 97) && (tolower(words[i]) <= 122)){
counts[(int)tolower(words[i]) - 97] = counts[(int)tolower(words[i]) - 97]+1;
}
}
for(int i = 0; i < counts.size()-1; i++){
total_letters = total_letters + counts[i];
}
ifs.close();
ifs.clear();
}
for(int i = 0; i < counts.size()-1; i++){
cout << endl << (char)i + 65 <<": " << counts[i] << ", " << ((double)counts[i]/total_letters)*100 << "%";
}
return 0;
}
答案 0 :(得分:1)
你已经制作了一个向量数组,而不是一个简单的向量。你应该像这样制作矢量:
vector<double> counts('z'-'a'+1, 0);
'z'-'a'+1
是另一种写作方式26.这种写入向量长度的方式让读者不会怀疑数组的目的(计算字母)。
现在你需要做的就是写counts[index]++
。
请注意,应避免使用硬编码97
和122
。
您需要在循环中阅读words
。这一行
ifs >> words;
读取单个单词,而不是所有单词。主循环应如下:
string word;
while (ifs >> word) {
for (int i = 0 ; i != word.size() ; i++) {
ch = word[i];
if (!isalpha(ch)) {
continue;
}
counts[tolower(ch)-'a']++;
}
}