思路:将给定文件按行读入–>去除每行中出现的非字母字符–>以空格分隔读入每个单词–>统计单词出现的次数。
按行读入文件并保存到一个string中
string tmp, strFile;
ifstream file("1.txt");
while (getline(file, tmp))
{
strFile.append(tmp);
tmp.clear();
}
这样做的结果是将文件中的所有行按顺序保存在了一个string中
去除非字母字符
for (size_t i = 0; i < strFile.length(); i++)
{
if (ispunct(strFile[i]))
strFile[i] = ' ';
}
将所有非字母字符以空格替代,这样使得输入文件中的单词间均已空格间隔
统计单词
stringstream ss(strFile);
string word;
while (ss >> word)
{
number_of_words++;
unordered_map<string, int>::iterator it = strMap.find(word);
if (it == strMap.end())
strMap.insert(unordered_map<string, int>::value_type(word, 1));
else
strMap[word]++;
}
首先使用stringstream从strFile中读取string,然后按空格间隔读取每个单词并统计:对于不存在的单词在unordered_map中增加一个键值对,存在则只增加计数。
结果写入文件
freopen("out.txt", "w", stdout);
printf("---------------------------------------------------\n");
printf("%d words be counted! \nDetails are as follow:\n", number_of_words);
printf("word times frequency\n");
printf("---------------------------------------------------\n");
unordered_map<string, int>::const_iterator it;
for (it = strMap.begin(); it != strMap.end(); it++)
{
printf("%-20s %-5d %17.2lf%%\n", (it->first).c_str(), it->second, it->second*100.0/number_of_words);
}
这里使用freopen函数将统计结果写入文件。
完整代码
#include <iostream>
#include <fstream>
#include <sstream>
#include <unordered_map>
#include <cctype>
using namespace std;
int number_of_words = 0;
unordered_map<string, int> strMap;
void getCount(stringstream &ss);
int main()
{
//读取文件并存入string
string tmp, strFile;
ifstream file("1.txt");
while (getline(file, tmp))
{
strFile.append(tmp);
tmp.clear();
}
//去除非字母字符
for (size_t i = 0; i < strFile.length(); i++)
{
if (ispunct(strFile[i]))
strFile[i] = ' ';
}
//依次读取单词并统计次数
stringstream ss(strFile);
getCount(ss);
freopen("out.txt", "w", stdout);
printf("---------------------------------------------------\n");
printf("%d words be counted! \nDetails are as follow:\n", number_of_words);
printf("word times frequency\n");
printf("---------------------------------------------------\n");
//打印统计结果
unordered_map<string, int>::const_iterator it;
for (it = strMap.begin(); it != strMap.end(); it++)
{
printf("%-20s %-5d %17.2lf%%\n", (it->first).c_str(), it->second, it->second*100.0/number_of_words);
}
return 0;
}
void getCount(stringstream &ss)
{
string word;
while (ss >> word)
{
number_of_words++;
unordered_map<string, int>::iterator it = strMap.find(word);
if (it == strMap.end())
strMap.insert(unordered_map<string, int>::value_type(word, 1));
else
strMap[word]++;
}
}