作业3词频统计

(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,大写转小写要加上32
        a++;
    }
	return 0;
}
int Judge(char w[])//判断是否符合题意的单词
{
     for (int e = 1; w[e] != '\0';)
    {
		 if(strlen(w)<4)//判断单词字长是否超过以及等于4
	   	return -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;
        else
            e++;
	}
	 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,第二判断首字母是否为字母,第三判断字母中是否有非字母数字。这个是借助大神帮忙,才能够写出来,这个真的很难啊。花了我不少心血啊。第四个模块完成。然后最重点的来了,计算词频。用指针访问单词在与下一个单词比较,相同加一,知道访问到字符串末尾在结束。

将他们组合起来更是花了好长时间。

希望以后老师在布置作业的时候,能够将每一次的交作业时间用红色标注一下,不要模棱两可的给个时间!!

posted @ 2016-03-16 19:58  吴敏2  阅读(241)  评论(0编辑  收藏  举报