zoukankan      html  css  js  c++  java
  • 作业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] != '')//当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] != '';)
        {
    		 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 << '
    ';
            c++;
        }
        return 0;
    }
    

      我按照我模块的顺序即 从文件中读取——>大写字母转为小写字母(为了不区分大小写,函数为Change)——>把句子按照分隔符分割开来(运用strtok函数)——>判断是否符合题意的单词(函数为Judge)——>计算单词出现的频率(函数Fre)。

    运行出的结果:

    总结:在这次编写过程中,我发现这个果然一点都不简单。说起来一套一套的,但是真正实施起来还是很有难度的。除了一个读取文件原先写过之外其他的感觉都是第一次接触。第一个大写转小写在汇编里写的很顺溜,但是在C++中是第一次写,课本中并没有提及,所以只能借助百度来解决,百度还真有,所以第二个模块解决了。分隔句子又是一个大难题,于是我再次借助百度大神来,但是百度上的答案都不一样,所以我挑了一个我最能理解方式利用strtok(char s[],const char *delim)函数来写。利用delim定义分隔符。第三个模块完成。判断单词的条件,第一判断字长不小于4,第二判断首字母是否为字母,第三判断字母中是否有非字母数字。这个是借助大神帮忙,才能够写出来,这个真的很难啊。花了我不少心血啊。第四个模块完成。然后最重点的来了,计算词频。用指针访问单词在与下一个单词比较,相同加一,知道访问到字符串末尾在结束。

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

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

  • 相关阅读:
    git track
    npm 升级到最新版本
    三行代码实现垂直居中和cube
    布局之定位
    MongoDB的安装问题
    正则表达式
    javascript表单验证
    Oracle中创建表,行级触发器,序列
    查找某个字符在字符串中出现的次数
    oracle表中有一列id她是自动增长的,插入一条数据时怎么取得id的值
  • 原文地址:https://www.cnblogs.com/wumin2/p/5284888.html
Copyright © 2011-2022 走看看