软件工程概论作业一 信1205班 20122561 董文轩

上周一,我们老师给我们布置了一个作业,内容如下:

写一个程序,分析一个文本文件(英文文章)中各个词出现的频率,并把频率最高的10个词打印出来。

这个程序看似简单,而实际上需要很多知识。比如:文件的读写,单词的存储,单词出现频率的统计与排序。首先我必须承认,这个问题对我来说很难,我自己无法把它完成,所以本次作业是我在请教同学和上网查阅资料的情况下完成的。但是,我想通过这样写这样的程序,尤其是这些自己平时没怎么练过的程序,可以给我添加许多知识,我很感激我们的王老师,通过这样的方式,我想让自己一步步提高。

然后,我们来分析此问题:

1、对于文件的读写,我用的是文件的指针,通过文件指针来实现;

2、对于单词的存储,我通过建立一个类,用链表的方式实现单词的存储,而且建立的这个类里包含了单词的存储,单词的个数还有单词出现的次数统计:

3、对于单词出现频率的统计,我通过建立相关函数实现。

本程序源代码如下:

#include <iostream>

#include <string>

#include <ctype.h>

#include <iomanip>

#include <fstream>

using namespace std;

#define MAX 2000

char pText[MAX];

char ch;

FILE *fp,*out;

//单词类

class Words

{

    public:Words(string str)

        {

            count=1;

            word=str;

            next=NULL;

        }

        int count; //出现的次数

        string word;

        Words *next;

};

class WordList

{

        public:

        void AddWord(string word); //添加单词

        bool WordExist(string word); //判断单词是否存在

        void WordPrint(); //打印出现次数最多的前五个单词

        int getLength(){ return length;}//单词链表长度

        int getTotal(){ return total;} //输入单词总数

        WordList();

        ~WordList();

    private:

        Words *first;

        Words *last;

        int length;

        int total;

};

WordList::WordList()

{

    first=new Words(" ");

    first->next=NULL;

    last=first;

    length=0;

    total=0;

}

WordList::~WordList()

{

    Words *p=first;

    Words *q;

    while(p!=NULL)

    {

        q=p;

        p=p->next;

        delete q;

    }

}

 

void WordList::AddWord(string word)

{

    if( !WordExist(word) )//单词不存在

    {

        Words *node=new Words(word);

        last->next=node;

        last=node;

        last->next=NULL;

        length++;

    }

}

 

bool WordList::WordExist(string word)

{

    Words *p=first->next;

    total++;

    while(p!=NULL)

    {

        if( p->word == word )

        {

            p->count++;

            return true;

        }

        p=p->next;

    }

    return false;

}

void WordList::WordPrint()

{

    int n=10;

    if( length < n)

    {

        n=length;

        cout<<"\n不同的单词不足10个\n";

    }

 

    cout<<setw(20)<< setiosflags( ios::left )<<"单词"<<setw(20)<< setiosflags( ios::left )

    <<"出现次数"<<setw(20)<< setiosflags( ios::left )<<"频率"<<endl;

    for( int i=0; i<n; i++ )

    {

        Words *p=first->next;

        string str=p->word;

        int max=p->count;

        Words* pmax=p;

        while(p!=NULL)

        {

            if( p->count > max )

            {

                max = p->count ;

                str=p->word;

                pmax=p;

            }

            p=p->next;

        }

        pmax->count=0;

        cout<<setw(20)<< setiosflags( ios::left )<<str<<setw(20)<< setiosflags( ios::left ) <<max<<setw(20)<< setiosflags( ios::left )<<1.0*max/total<<endl;

    }

}

 

class Text

{

    string txt;

    WordList mywords;

    public:

        void PutIn();

        void PutOut();

        void Run();

};

 

bool readFileToString(string file_name, string& fileData)

 {

 

 

    ifstream file(file_name.c_str(),  std::ifstream::binary);

   

     if(file)

     {

         // Calculate the file's size, and allocate a buffer of that size.

         file.seekg(0, file.end);

         const int file_size = file.tellg();

         char* file_buf = new char [file_size+1];

         //make sure the end tag \0 of string.

 

        memset(file_buf, 0, file_size+1);

       

         // Read the entire file into the buffer.

         file.seekg(0, ios::beg);

         file.read(file_buf, file_size);

 

 

        if(file)

         {

             fileData.append(file_buf);

         }

         else

         {

             std::cout << "error: only " <<  file.gcount() << " could be read";

             fileData.append(file_buf);

             return false;

         }

         file.close();

         delete []file_buf;

     }

     else

     {

         return false;

     }

 

 

    return true;

 }

 

void Text::PutIn()

{

  /* readFileToString("c:/english.txt", txt);

   cout<<"File data is:\r\n"<<txt<<endl;

   cout<<"Failed to open the file, please check the file path."<<endl;

   */

   

    int k=0;

    char infile[20];

    cout<<"输入读入文件的路径:"<<endl;

    scanf("%s",infile);

    readFileToString(infile, txt);

 

    if((fp=fopen(infile,"r"))==NULL)

    {

        printf("文件无法打开!!\n");

        exit(0);

    }

    while(!feof(fp))

    {

        ch=fgetc(fp);

        pText[k++]=ch;

    }

 

 

    fclose(fp);

    k--;

    pText[k]='#';   

}

 

 

void Text::Run()

{

    int i=0;

    while( i<txt.length())

    {

        string temp;

        while( !isalpha(txt[i]) && i<txt.length())

        {

            i++;

        }

        while( isalpha(txt[i]) && i<txt.length())//如果参数是字母字符

        {

            temp=temp+txt[i];

            i++;

        }

        if(i<txt.length())

        {

            mywords.AddWord(temp);

        }

    }

}

void Text::PutOut()

{   cout<<"*****************************************"<<endl;

    cout<<"文件中共"<<mywords.getTotal()<<" 个单词,其中"<<mywords.getLength()<<" 个不同的单词"<<endl;

    cout<<"*****************************************"<<endl;

    cout<<"\n出现频率最高的10个单词: \n";

    mywords.WordPrint();

}

void main()

{

    Text mytest;

    mytest.PutIn();

    mytest.Run();

    mytest.PutOut();

    system("pause");

}

 

本次作业虽然遇到了很大问题,但在求助网上高人和同学帮助的情况下,完成了此次作业。因此,我要努力学习编程语言,提高自己的能力。

 

posted @ 2014-03-03 08:54  dashendwx  阅读(169)  评论(0编辑  收藏  举报