软件第四次作业
作业要求
- 基于作业3的结果,读取一个较小的文本文件A_Tale_of_Two_Cities.txt,统计该文件中的单词的频率,并将统计结果输出到当前目录下的 Result1.txt 文件。 (第一阶段初稿完成该要求)
- 命令行格式: 提示符> Myapp.exe -f filename.txt > Result.txt (PS:C++ 程序,Java 程序输出方式类似) filename.txt 为前面下载的文件名。
- 解释:
- 选项 -f 表示后面跟文件名
- 输出格式规定(参考作业3中的示例):
- 首先按照频率由高到低排序
- 频率一样的词, 按照字典顺序排序
- 此外, 读取一个较大的文本文件Gone_with_the_wind.txt实验对比程序执行效率,做如下改进,比较改进前后程序执行时间。PS: 请看一位同学做的效能分析示例。
结对对象:钱佳晨
Github:https://github.com/TYshadow/TYshadow/blob/master/4.cpp
作业共同讨论修改 大致55开
int main()
{
int wCount = 1;
Word * words;
string content;
string addition;
const char *delim = " ,' '“”.''-‘’!?";
ifstream file("e://Gone_with_the_wind.txt"); //读取
ofstream fout("e://Result1.txt");
if (!file)
{
cout << "Unable to open ";
exit(1);
}
while (!file.eof())
{
getline(file,addition);
content.append(addition); //分段读取文本
}
file.close();
unsigned int len = content.length();
for (unsigned int i = 0; i < len; i++)
{
if (isalnum(content[i]) == 0) //非字母数字
{
wCount++;
}
}
cout << wCount;
words = new Word[wCount];
string::size_type offset = content.find_first_of(delim); //单词分隔;size_type用以保存string对象的长度
while (offset != string::npos)
{
string wStr = content.substr(0, offset); //string.substr()返回一个从指定位置返回指定长度的字符串
if (wStr.length() < 4) //除去长度小于4的单词
{
wCount--;
content.erase(0, offset + 1);
offset = content.find_first_of(delim);
continue;
}
content.erase(0, offset + 1); //string.erase()删除从指定位置开始的指定长度的字符
transform(wStr.begin(), wStr.end(), wStr.begin(), ::tolower);
CalcCount(words, wStr, wCount);
offset = content.find_first_of(delim);
}
if (content.length() >= 4)
{
transform(content.begin(), content.end(), content.begin(), ::tolower);
CalcCount(words, content, wCount); //计算最后一个单词
}
else wCount--;
for (int i = 0; i < wCount; i++)
{
if (words[i].Str == "")
{
wCount--;
}
}
SortWord(words, wCount);
SortWordDown(words, wCount);
fout << "词频统计:" << endl;
for (int i = 0; i < wCount - 1; i++)
{
fout << words[i].Str << "\t频率:" << words[i].Count << "次" << endl;
}
fout << "调用该程序所花费的时间为:" << clock() << "毫秒\n";
delete[] words;
return 0;
}
总结:首先用了find_first_of函数解决了上次分隔符的问题,无论哪一种语言,它们的类库都很重要,熟悉掌握这些能够节省很多时间。然后这次的文件读取中,一开始发现大文件无法读取,花了大把时间调试找问题,最后原因还是对函数功能的理解出现偏差,和大钱商讨后选择了分段读取的方式,多一个人可以更加坚定自己的想法,并且确实可以纠正一些思维上的死角。最后再效能分析上,用clock()函数计算了时间,大概是程序偏小,感觉差别并不很大。程序仍待改进。