magic code 李亚文

 

【软件工程】把文本文件中频度最高的10个词打印出来 编程日志之我就这么点水平

先看结果:

#include <iostream>
#include <fstream>
#include <string>
#include<stdlib.h>
using namespace std;

FILE *f1;    //读文件

struct kw                  //存放单词及其个数
    {
        int key;
        char a[20]; 
        
    };


char c[20];
struct kw list[300];

void crehash()    //把单词存入表中
{
    char ch;
    int k,flag=0,n=0,m=0,j=0;
    for(m=0;m<200;m++)                  //将list中的key值全部初始化为0
    list[m].key=0;
    if((f1=fopen("c:\\urce2.txt","r"))==NULL)            //判断文件是否存在     
       cout<<"文件无法打开"<<endl;
    else
    while(!feof(f1))                        
    {
        ch=fgetc(f1);
        for(k=0;k<20;k++)
            c[k]='\0';
        int i=0;
        while(((ch>63&&ch<91)||(ch>96&&ch<123)))           //判断是否是字母
        {
            if(ch>63&&ch<91) 
                ch=ch+32;
             c[i++]=ch;
            ch=fgetc(f1);
         }
        if(c[0]=='\0') continue;                        //如果c中没有存进内容则不进行比较
        else
        { 
        for(j=0;list[j].key!=0;j++)                            
        {
            if(strcmp(list[j].a,c)==0)                        //如果相同则使Key+1                  
            {
                list[j].key=list[j].key+1;
                flag=1;
                break;
            }
        }
        if(flag==0)
        {
            list[j].key=1;                                     //否则key=1,将C存入数组中
            strcpy(list[j].a,c);
        }
        
        flag=0;
       
        }                         
    } 
fclose(f1);
                           
}

void sort()                              //排序函数,冒泡法只需要10次
{
    int i,j,max;
    char ch2[20];
    for(i=0;i<10;i++)
    {
        max=list[i].key;
        for(j=i+1;list[j].key!=0;j++)
            if(list[j].key>max)
            {
                max=list[j].key;
                list[j].key=list[i].key;
                list[i].key=max;
                strcpy(ch2,list[j].a);
                strcpy(list[j].a,list[i].a);
                strcpy(list[i].a,ch2);
            }
            cout<<list[i].a<<'\t'<<list[i].key<<'\t'<<endl;
    }
}

void main()
{
    int i;
    crehash();
//    cout<<"单词"<<'\t'<<'\t'<<"个数"<<'\t'<<endl;
//    for(i=0;list[i].key!=0;i++)
  //   cout<<list[i].a<<'\t'<<'\t'<<list[i].key<<'\t'<<endl;           //输出单词以及其个数
    cout<<"出现频率最高的前十个词是:"<<endl;
    sort(); 
    
}

一、解题思路

1、定义一个结构体,如下,a用来存放单词,key用来存放单词的个数,结构体数组为list,并且将key的值都初始化为0;

struct kw                  //存放单词及其个数
    {
        int key;
        char a[20]; 
        
    };

 2、将单词及其个数存入结构体数组,具体方法如下

     要包括读文件,一个字母一个字母的读,然后将单词存入字符数组c中,用c与结构体数组的值相比较,如果与A相同就使key+1,否则,就使下一个key为0的结构体置为1,a置为c的值。循环直到文件结束。

void crehash()    //把单词存入表中
{
    char ch;
    int k,flag=0,n=0,m=0,j=0;
    for(m=0;m<200;m++)                  //将list中的key值全部初始化为0
    list[m].key=0;
    if((f1=fopen("c:\\urce2.txt","r"))==NULL)            //判断文件是否存在     
       cout<<"文件无法打开"<<endl;
    else
    while(!feof(f1))                        
    {
        ch=fgetc(f1);
        for(k=0;k<20;k++)
            c[k]='\0';
        int i=0;
        while(((ch>63&&ch<91)||(ch>96&&ch<123)))           //判断是否是字母
        {
            if(ch>63&&ch<91) 
                ch=ch+32;
             c[i++]=ch;
            ch=fgetc(f1);
         }
        if(c[0]=='\0') continue;                        //如果c中没有存进内容则不进行比较
        else
        { 
        for(j=0;list[j].key!=0;j++)                            
        {
            if(strcmp(list[j].a,c)==0)                        //如果相同则使Key+1                  
            {
                list[j].key=list[j].key+1;
                flag=1;
                break;
            }
        }
        if(flag==0)
        {
            list[j].key=1;                                     //否则key=1,将C存入数组中
            strcpy(list[j].a,c);
        }
        
        flag=0;
       
        }                         
    } 
fclose(f1);
                           
}

3、排序并打印前十个,用的是冒泡法。

二、编程日志

开发项目,在英语文章中查出频度最高的10个词。

2014年2月24日星期一

18:40-19:00画出了流程图。
19:00-19:30实现了排序算法的编写,很简单,但是思路要清晰
19:30-20:00实现了字符串的比较,发现strcmp不适合string型的数据,只适合数组型即适用于c不适合c++,所以不能用两个字符串比较。。。。
20:00-22:00写出了将单词个个数存放到结构体的函数,编译没有错误,但是执行通过不了,调试很费劲。肚子有点饿,头有点晕,我决定明天继续做,其实关键是搞清楚指针到底在哪里。

2014年2月27日

14:00-16:00:继续调试,手动调试,但是由于循环很多,过程很繁琐,到最后也没调出来,只是知道了是读文件的错误,是文件结束的时候会产生一个类似于y的字符,使得程序无法结束,但是找不到解决方案。

19:00-22:30:寻找解决方案,我试图把C++文件读取方式变成C语言的文件读取方式,但是没有效果。继续手动调试好几遍才知道,是将单词存入数组的时候没有考虑是否到了文件末尾导致的,后来加上了一个条件,如下

while(ch!=' '&&ch!=','&&ch!='.'&&ch!=10&&!feof(f1))

单词的数量可以统计出来了,但是有错误,总是有一个空格字符个数出现。

2014年3月1日

19:00-22:30

 总是会有一个空格字符出现,很奇怪他的个数和标点还有换行的个数相同,于是就找错误,请教了任国庆同学后知道,原来C++中数组清空时数组中的'\0'依然会占用空间,于是就出现了一个空格的个数,改成null也不奏效,最后只好加上了一个判断条件如下:

 if(c[0]=='\0') continue;                        //如果c中没有存进内容则不进行比较
        else 继续使C中的单词与结构体数组中的比较

这样就可以判断了;

加入排序函数的时候也出现了问题,因为写的时候是按照整型数组写的排序,但是到了结构体这里就不适用了,交换的时候要分别交换,如下

max=list[i].key;
        for(j=i+1;list[j].key!=0;j++)
            if(list[j].key>max)
            {
                max=list[j].key;
                list[j].key=list[i].key;
                list[i].key=max;
                strcpy(ch2,list[j].a);
                strcpy(list[j].a,list[i].a);
                strcpy(list[i].a,ch2);
            }


这样才能实现排序。

 

后来用了较长的文章测试,发现如果有“?”或者“;”将无法识别出来,于是就改进了,改变了判断的条件改成判断读入的字符是不是字母,如果是大写字母还要转换成为小写,如下:

while(((ch>63&&ch<91)||(ch>96&&ch<123)))           //判断是否是字母
        {
            if(ch>63&&ch<91) 
                ch=ch+32;
             c[i++]=ch;
            ch=fgetc(f1);
         }

如果早就想到这个条件,就不会用判断是否为文件尾部的字符了,条件还简单可靠。

三、运行结果:

文章内容:

We are  reading the first verse of the first chapter of a book whose pages are infinite
  I do not know who wrote those words, but I have always liked them as a reminder that the future can be anything we want to make it. We can take the mysterious, hazy future and carve out of it anything that we can imagine, just as a sculptor carves a statue from a shapeless stone.
  We are all in the position of the farmer. If we plant a good seed, we reap a good harvest. If our seed is poor and full of weeds, we reap a useless crop. If we plant nothing at all, we harvest nothing at all.
  I want the future to be better than the past. I do not want it contaminated by the mistakes and errors with which history is filled. We should all be concerned about the future because that is where we will spend the remainder of our lives.
  The past is gone and static. Nothing we can do will change it. The future is before us and dynamic. Everything we do will affect it. Each day brings with it new frontiers, in our homes and in our business, if we only recognize them. We are just at the beginning of the progress in every field of human endeavor.

运行结果:

出现频率最高的前十个词是:
we      16
the     15
of      8
a       8
it      6
and     6
future  5
is      5
can     4
i       4
Press any key to continue

 

心得:

条件很重要,要搞清条件,必须有清醒的大脑;

具体问题具体分析,算法不变但是对于不同的数据类型要有不同的实现方法;

变成习惯很重要,往往小错误最折磨人。

水平真的有待提高。
 

posted on 2014-03-01 22:45  magic code 李亚文  阅读(545)  评论(2编辑  收藏  举报

导航