上周一,我们老师给我们布置了一个作业,内容如下:
写一个程序,分析一个文本文件(英文文章)中各个词出现的频率,并把频率最高的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");
}
本次作业虽然遇到了很大问题,但在求助网上高人和同学帮助的情况下,完成了此次作业。因此,我要努力学习编程语言,提高自己的能力。