(1). 实现一个控制台程序,给定一段英文字符串,统计其中各个英文单词(4字符以上含4字符)的出现频率。
答:
从文件读取 | 遍历字符串 | 大写转小写 | 将句子分隔成一个个单词 | 判断是否为单词 | 计算单词出现的频率 | |
预估时间 | 10minutes | 10minutes | 20minutes | 40minutes | 1hours | 2hours |
实际时间 | 5minutes | 5minutes | 15minutes | 1hours | 2hours | 2hours |
在写这次作业之前我认为只是一个简单统计题,但是看了一眼老师的要求之后,就开始有点疯了。一个要求一个要求的提出来,重叠在一起,我就发现无从下手了。又是大小写不区分,又是单词的要求长度不小于4,什么什么的。我发现就这么一个简单的编程题能被老师改成这样,老师真是煞费苦心啊。既然要求这么多,我就把每个要求一个一个拆开分析,然后再试着将他们组装起来。
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;struct Num{int num;char *s;
};Num word[999];int Change(char str[999])//大写转小写
{int a = 0;while (str[a] != '\0')//当str字符串未结束时将大写字母转小写{if (str[a] >= 'A'&&str[a] <= 'Z')str[a] = str[a] + 32;//因为大写字母与小写字母的ascll码值相差32,大写转小写要加上32a++;}return 0;
}
int Judge(char w[])//判断是否符合题意的单词
{for (int e = 1; w[e] != '\0';){if(strlen(w)<4)//判断单词字长是否超过以及等于4return -1;if (w[e] >= 'a' && w[e] <= 'z')//判断单词的首字符是否是字母return -1;if (!((w[e] >= 'a' && w[e] <= 'z') || (w[e] >= '0' && w[e] <= '9')))//判断单词中是否有非字母数字return -1;elsee++;}return 0;
}
int Fre(char f[],int total ) //统计单词出现过的频率
{if (total>0)for (int i = 0; i <total; i++){if (!strcmp(f, word[i].s)) {word[i].num++; return -1;}}return 0;
}int main()
{ char sentence[999];ifstream file("d://test.txt"); //读取if (!file){cout << "Unable to open ";exit(1); }while (!file.eof()){file.getline(sentence,999);}file.close();const char *delim = ",“”.' '‘’!?"; //delim是用来定义分隔符的内容char *p= strtok(sentence, delim);//strtok函数根据分隔符分隔字符串int n=0;int c=0;while (p){Change(p);if (Judge(p) != -1){if (Fre(p, n)!=-1){word[n].s = p;n++;}}p = strtok(NULL, delim);}while (word[c].s) //输出统计结果{cout << word[c].s<< ":" << word[c].num << '\n';c++;}return 0;
}
我按照我模块的顺序即 从文件中读取——>大写字母转为小写字母(为了不区分大小写,函数为Change)——>把句子按照分隔符分割开来(运用strtok函数)——>判断是否符合题意的单词(函数为Judge)——>计算单词出现的频率(函数Fre)。
运行出的结果:
总结:在这次编写过程中,我发现这个果然一点都不简单。说起来一套一套的,但是真正实施起来还是很有难度的。除了一个读取文件原先写过之外其他的感觉都是第一次接触。第一个大写转小写在汇编里写的很顺溜,但是在C++中是第一次写,课本中并没有提及,所以只能借助百度来解决,百度还真有,所以第二个模块解决了。分隔句子又是一个大难题,于是我再次借助百度大神来,但是百度上的答案都不一样,所以我挑了一个我最能理解方式利用strtok(char s[],const char *delim)函数来写。利用delim定义分隔符。第三个模块完成。判断单词的条件,第一判断字长不小于4,第二判断首字母是否为字母,第三判断字母中是否有非字母数字。这个是借助大神帮忙,才能够写出来,这个真的很难啊。花了我不少心血啊。第四个模块完成。然后最重点的来了,计算词频。用指针访问单词在与下一个单词比较,相同加一,知道访问到字符串末尾在结束。
将他们组合起来更是花了好长时间。
希望以后老师在布置作业的时候,能够将每一次的交作业时间用红色标注一下,不要模棱两可的给个时间!!