zoukankan      html  css  js  c++  java
  • 【第二周】【作业八】个人项目词频统计++

    拖延症又犯了,不想写作业,但是冥冥之中想到了一句话:与其感慨路难行,不如马上出发。出自dota英雄骷髅弓箭手——克林克兹。于是就这样把我从泥潭中捞了出来。

     ——————————————————————————————————————————————————————

    由于涉及到以后效率评判的问题,重新写了下代码。主要思想是利用二叉排序树结点存储英文单词,然后中序遍历树,将树的信息读取到结构体中,按照单词的频率排序并输出结果。

    下面来说一下各部分代码:

    1.树的节点的结构体,word用来储存单词的字符信息,考虑到几乎没有单词超过50字符长度,所以长度max设置为50,count是单词个数,*left和*right是指向左右儿子节点的指针。

    1 stru啊ct tnode{asdas
    2     char word[MAX];
    3     int count;
    4     struct tnode *left,*right;
    5 }; 

    2.准备用来存储结点内容的表的结构体,理所当然,w要拷贝tnode中word的内容,所以长度也是50。

    1 typedef struct word{
    2     int num;
    3     char w[50];
    4 }List;

    3. cmp()函数,比较两个字符的大小,为以后的qsot做准备。

    1 int cmp(const void *a,const void *b)
    2 {
    3     List *p1 = (List*)a;
    4     List *p2 = (List*)b;
    5     if(p1->num!=p2->num)
    6         return p2->num-p1->num;
    7     else
    8         return strcmp(p1->w,p2->w);
    9 }

    4.treeword()函数,作用是构建一个word树,传入一个结点指针(通常是根节点)和一个字符串指针,将word插入树的适当位置(与根节点作对比,若字符小于根节点字符,继续向做遍历,否则向右,直到访问到空指针,生成新的叶子节点),若指向的是树中原有的单词,则对应结点的num增加,若没有按照前面流程生成叶子节点。

     1 struct tnode* treewords(struct tnode *p,char *w)
     2 {
     3     int cond;
     4     if(p==NULL){
     5         p=(struct tnode*)malloc(sizeof(struct tnode));
     6         strcpy(p->word,w);
     7         p->count=1;
     8         p->left=p->right=NULL;
     9     }
    10     else if((cond=strcmp(w,p->word))==0)
    11         p->count++;
    12     
    13     else if(cond<0)
    14         p->left=treewords(p->left,w);
    15     
    16     else
    17         p->right=treewords(p->right,w);
    18     return (p);
    19 }

    5.treeprint()函数,传入一个节点指针(通常为根节点),然后将其作为根节点中序遍历整个子树。期间arr储存所有节点指针,并得到curr,节点的数目。

     1 void treeprint(struct tnode *p)
     2 {
     3     if(p!=NULL){
     4           
     5         treeprint(p->left);
     6         arr[curr++]=p;
     7         treeprint(p->right);    
     8       
     9     }
    10 }

    6,主函数,较复杂,先贴出整个代码:

     1 int main()
     2 {
     3     char word[MAX];
     4     char *fname ; 
     5     FILE *fin;
     6     FILE *fout; 
     7     char c;
     8     int i,k,n;
     9     struct tnode *root;
    10     root=NULL;
    11   
    12     
    13     printf("文件输入请按一,标准输入请按二:");
    14     int sflag;
    15     scanf("%d",&sflag);
    16      
    17     if(sflag==1)
    18     {
    19     printf("请输入文件名称: ");
    20     scanf("%s",fname); 
    21     fin = fopen(fname,"r");
    22       fout = fopen("result.txt","w");
    23     }
    24     else
    25     {
    26     fin = stdin;
    27     fout = stdout;    
    28     }
    29    
    30     while((c=fgetc(fin))!=EOF){
    31        ungetc(c,fin);
    32         for(i=0;(c=fgetc(fin))!=' '&&c!='
    '&&c!=EOF;i++)
    33         {
    34             if((c>='A'&&c<='Z')||(c>='a'&&c<='z'))
    35             {
    36                 c=tolower(c);
    37                 word[i]=c;
    38             }else
    39                 break;
    40         }
    41         word[i]='';
    42         if(strlen(word)>0)
    43             root=treewords(root,word);
    44     }
    45     
    46     treeprint(root);
    47     
    48     for(i=0;i<curr;i++)
    49     {
    50         list[i].num=arr[i]->count;
    51         strcpy(list[i].w,arr[i]->word);
    52     }
    53     n=curr;
    54     qsort(list,n+1,sizeof(list[0]),cmp);
    55  
    56     for(k=0;k<curr;k++)
    57     {
    58         fprintf(fout,"%s %d
    ",list[k].w,list[k].num);
    59     }
    60     for(k=0;k<10;k++)
    61     {
    62         printf("%s %d
    ",list[k].w,list[k].num);
    63        
    64     }
    65     fclose(fin);
    66     fclose(fout);
    67     printf("Time used = %lf",(double)clock()/CLOCKS_PER_SEC);
    68     return 0;
    69 }

     (1) 首先,这几行代码是选择文件输入,还是标准输入输出的,重定向更简单,只需要调用一下freopen。

        printf("文件输入请按一,标准输入请按二:");
        int sflag;
        scanf("%d",&sflag);
         
        if(sflag==1)
        {
        printf("请输入文件名称: ");
        scanf("%s",fname); 
        fin = fopen(fname,"r");
          fout = fopen("result.txt","w");
        }
        else
        {
        fin = stdin;
        fout = stdout;    
        }

    (2)读入字符,一直读到EOF,并且检查字符串合法性,遇到大写字母转化为小写,不能同个单词统计两次。后面是将字符长度大于0的单词传入word树。

     1   while((c=fgetc(fin))!=EOF){
     2 3         for(i=0;(c=fgetc(fin))!=' '&&c!='
    '&&c!=EOF;i++)
     4         {
     5             if((c>='A'&&c<='Z')||(c>='a'&&c<='z'))
     6             {
     7                 c=tolower(c);
     8                 word[i]=c;
     9             }else
    10                 break;
    11         }
    12         word[i]='';
    13         if(strlen(word)>0)
    14             root=treewords(root,word);
    15     }

    (3)将arr的数据拷贝到list,然后利用list进行快排,然后两个for循环,一个是将结果写入txt,一个是将前十个结果输出到屏幕上。

     1  treeprint(root);
     2     
     3     for(i=0;i<curr;i++)
     4     {
     5         list[i].num=arr[i]->count;
     6         strcpy(list[i].w,arr[i]->word);
     7     }
     8     n=curr;
     9     qsort(list,n+1,sizeof(list[0]),cmp);
    10  
    11     for(k=0;k<curr;k++)
    12     {
    13         fprintf(fout,"%s %d
    ",list[k].w,list[k].num);
    14     }
    15     for(k=0;k<10;k++)
    16     {
    17         printf("%s %d
    ",list[k].w,list[k].num);
    18        
    19     }

     

    下面展示运行结果:

    1.从控制台输入文件名,然后在屏幕输出结果,并且同时生成一个txt保存结果。

    2,从控制台选择标准输入输出。

    3.从cmd运行程序,输入文件名运行。

    4,从cdm运行程序,进行标准输入输出。

    5,其余关于批量处理的还没有研究。

    最最关键的必做题来了

    1.个人项目耗时记录表1,B列是计划时间,D列是实际时间。

    2.表二

    项目:词频统计++

    项目类型:个人项目

    项目完成情况:已完成

    项目改进:未变更

    项目日期:2016.9.12-2016.9.13

    12号

    类别c 内容c 开始时间s 结束e 中断I 净时间T
    项目实践 计划  9:20  9:45 5m 20m
    项目实践 需求分析 10:00 10:40 10m 30m
    项目实践 具体设计 10:40 13:50 130m 60m
    项目实践 编码 15:30 16:30 0m 60m
    项目实践 编码 20:30 24:00 30m 180m

    13号

    类别c 内容c 开始时间s 结束e 中断I 净时间T
    项目实践 编码 00:00 00:40 0m 40m
    项目实践 编码 10:30 11:30 10m 50m
    项目实践 编码 13:40 15:00 50m 30m
    项目实践 计算工作量 15:00 15:20 0m 20m
    项目实践 写博客 20:00 23:45 45m 180m

    对比表1,2,还是比较接近的,代码编写时间多了很多,那是编写时遇到了不少问题,网上比较水,关键时候还得认真看书。博客时间也多了一个小时,一是没想到写那么多,自己思路那么慢。

    二是这个博客老是崩溃,加个图自己就卡了,有时需要重写,浪费好多时间。在表格里写东西光标居然不跟着移动。

    最后,真的是眼睛好疼,先到这里了。

  • 相关阅读:
    神经网络系列学习笔记(一)——神经网络之ANN学习资料汇总
    时间序列分析算法学习笔记
    推荐算法学习笔记
    神经网络系列学习笔记(二)——神经网络之DNN学习笔记
    AB test学习笔记
    大数据的存储——HBase、HIVE、MYSQL数据库学习笔记
    本地已经存在的项目如何跟github发生关联
    深度神经网络对脑电信号运动想象动作的在线解码
    脑机音乐接口,高效检测用户的情绪状态
    将深度学习技术应用于基于情境感知的情绪识别
  • 原文地址:https://www.cnblogs.com/Boxer1994/p/5869980.html
Copyright © 2011-2022 走看看