英文单词使用频度统计 毕业设计论文

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据结构课程设计任务书
学院名称:数学与计算机学院课程代码:_________________
专业:软件工程年级:
一、设计题目
英文单词使用频度统计
二、主要内容
本设计属于数组链表的应用,统计英文文本文件中各单词的使用频度(使用次数/单词总数)。

要求使用数组链表存放文件中不同单词及出现的次数,数组链表的节点内容包括指向左右子树的指针、单词本身、使用次数。

基本操作过程是从文本文件中读取一个单词并插入数组链表并累计出现次数,文件读完,即按使用频度顺序输出各单词。

三、具体要求及提交的材料
1.做好设计计划,认真查阅相关资料,完成程序设计及调试;
2.按《课程设计说明书_实例模板》完成课程设计说明书的撰写;
3.设计结束后,必须上交如下材料:
(1)《课程设计说明书(报告)》打印稿一份;(2)课程设计说明书及源代码电子文档
四、主要技术路线提示
认真分析系统功能需求,拟定设计方案和程序框架,查阅相关资料,完成算法设计和程序调试。

五、进度安排
共计两周时间,建议进度安排如下:
1.选题,应该在上机实验之前完成
2.需求分析、方案拟定、程序框架思考可分配4学时
3.详细的程序设计可分配8学时
英文单词使用频度统计
4.调试和分析可分配8学时。

可以有2学时的机动,即提前完成设计任务的学生可提前安排程序验收和答辩
六、推荐参考资料
1.冯博琴等编著,《软件技术基础》(修改版),西安交通大学出版社,1997
2.严蔚敏等著,《数据结构》,清华大学出版社,2003
3.李芸芳等著,《软件技术基础》(第二版),清华大学出版社,2000
4.徐孝凯等著,《数据结构(C语言描述)》,清华大学出版社,2004
指导教师签名日期年月日
系主任审核日期年月日
- 2 -
目录
摘要
1 引言 (1)
2 需求分析 (1)
2.1用户需求 (1)
2.2功能需求 (1)
3 概要设计 (2)
3.1设计思路图解 (2)
3.1.1数据结构图解 (2)
3.1.2功能模块图 (2)
3.1.3模块调用图 (3)
3.1.4程序流程图 (4)
3.2编码设计思路 (5)
3.2.1抽象数据类型 (5)
3.2.2要模块设计 (7)
4 详细设计 (10)
4.1头文件代码设计 (10)
4.2详细代码设计 (12)
5 系统测试 (22)
5.1实现环境 (22)
5.2 语言选择 (22)
5.3 测试文件 (22)
5.4 测试分析 (23)
总结 (26)
致谢 (27)
参考文献 (28)
- 1 -
英文单词使用频度统计
摘要
本课程设计需要完成对信息中单词出现频率的统计。

信息中同一个单词可能出现的格式有所不同,通过大小写转换后统一为小写格式来比较。

在窗口中输出整个文件信息,给出输入提示,执行程序后输出要查询的单词出现的频率和位置。

- 2 -
1 引言
1.1问题的提出
随着社会的发展,人们学习热情高涨,考证热已经遍布全国,特别是大学生的四六级考试,及其他的英语考试,可谓是英语似乎占据了大家的大部分时间。

而这样便给很多出版社或知道书籍作者很多牟利的机会。

统计单词便是他们吸引同学购买的一中手段,如何才能快捷准确的统计出所给出的信息中的指定的单词出现频率呢,这样便孕育出了单词频率统计系统。

1.2任务与分析
本设计属于二叉树的应用,统计英文文本文件中各单词的使用频度(使用次数/单词总数)。

要求使用二叉排序树存放文件中不同单词及出现的次数,二叉树的节点内容包括指向左右子树的指针、单词本身、使用次数。

基本操作过程是从文本文件中读取一个单词并插入二叉排序树并累计出现次数,文件读完,即按使用频度顺序输出各单词。

2需求分析
2.1用户需求
用户可以通过该程序查询和统计一篇英文文章中某些特定单词出现次数和位置。

2.2功能需求
用户可以输入单词来查询单词出现次数和位置;
程序可以正确显示查询结果;
用户可以选择是否在一次输出后继续查询;
在一次查询中的结果记录到一个二维链表中。

- 1 -
3概要设计
3.1设计思路图解
3.1.1数据结构图解
图1 数据结构图解
将从文件流读入的文章字符存到szFile[]字符数组中,以空格计数行单词个数,以换行符记录文章列数,将输入后插入到链表中的单词与字符数组中的单词比较,遇到相等的则将当前的行列数插入到链表的位置结点中,并且单词个数加1。

本程序允许用户选择是否重复进行,并且对于在一次操作中重复输入的单词,在链表中不进行重复插入。

3.1.2功能模块图
图2功能模块图
- 2 -
3.1.3模块调用图
图3模块调用图
- 3 -
3.1.4程序流程图
图4程序流程图
- 4 -
3.2编码设计思路
3.2.1抽象数据类型
struct node
{
int col; //行坐标
int row; //所在行的列坐标
node* next; //指向下一个坐标结点的指针}; //单词坐标坐点类型
struct Node
{
char words[20]; //单词数组
node* ptr; //指向单词坐标结点的指针
Node* next; //指向下一个单词结点的指针
int num; //单词所含字符个数
}; //单词结点
class TLink
{
public:
TLink() { head = NULL; }
//构造函数
~TLink()
//析构函数
{
while( head != NULL )
{
Node* temp;
- 5 -
temp = head;
head = head -> next;
delete temp;
}
}
void Insert( char* Item );
//前条件:参数Item[]为一个字符数组。

//后条件:Item[]所包含的单词被插入到链表。

void calcute(char *szFile,int size);
//前条件:szFile[]以正确保存了文本字符,size为文本字符长度。

//后条件:统计链表每一个插入的单词的个数及所在行、列坐标。

Node* gethead();
//前条件:链表已初始化
//后条件:返回链表头指针
private:
Node* head;
};
char A_to_a( char alp );
//前条件:alp为一个正确的英文字母
//后条件:如果alp是大写字母,则转化为小写字母,否则不变。

void showwindow();
//后条件:显示统计结果。

void show_text();
//前条件:在正确的路径上存在一个英文文本。

//后条件:读入英文文本到字符数组并显示在屏幕上。

void input();
//后条件:读入用户输入的字符并插入到单词链表。

- 6 -
3.2.2主要模块设计
/*****************************************************************/
新建单词结点;
while( Item[i] != '\0' )
{
复制各字符到单词结点的单词数组中;
记录单词字母个数;
}
插入单词字母个数到链表相应域;
temp -> words[i] = '\0';
查找并比较链表中是否已有要插入的单词;
如果有
不进行插入并销毁新建结点;
否则
插入新建的单词结点;
}
/*****************************************************************/
统计函数( 参数:char *szFile, int size)
{
while( 没有到文本字符的结尾 )
{
依次遍历文本字符,遇到非字母字符时计数单词所含字母个数;
while( 没有到链表尾 )
{
if( 单词结点所含单词的字母个数与计数相等 )
{
忽略大小写比较本次遍历到的单词和链表中的结点单词;
if(相等)
插入行列值
}
}
遇空格行单词个数加1;
遇换行列数加1;
}
/****************************************************************/
结构显示模块
while( 没到链表尾 )
{
输出结点单词;
如果存在,则输出单词的所有行、列值及出现次数;
否则输出没有该词或输入错误信息;
}
/*************************************************************/
输入模块
{
do{
if( 链表不空 )
清空链表;
输出提示信息;
接受用户输入;
while( true )
{
输入的是结束字符;
退出;
记录输入逗号前的单词;
插入到链表;
继续输入;
}
if( 链表空 )
输出 "没有插入任何单词!";
else
{
统计;
显示结果;
}
提示是否继续;
输入;
}while( 不继续 );
}
4详细设计
4.1头文件设计
/******************头文件***********************/
//FILE:source.h
#ifndef SOURCE_H
#define SOURCE_H
struct node
{
int col;
int row;
node* next;
};
struct Node
{
char words[20];
node* ptr;
Node* next;
int num;
};
class TLink
{
public:
TLink() { head = NULL; }
~TLink()
{
while( head != NULL )
{
Node* temp;
temp = head;
head = head -> next;
delete temp;
}
}
void Insert( char* Item );
void calcute(char *szFile,int size);
Node* gethead();
private:
Node* head;
};
char A_to_a( char alp );
void showwindow();
void show_text();
void input();
#endif
//将链表类声明于头文件中便于调用,清晰易见。

4.2详细代码设计
//english.cpp
#include<iostream>
#include<fstream>
#include<cstdlib>
#include "source.h"
using namespace std;
TLink link;
int i=0;
char szFile[2000]; //定义一个足够长度的字符
/****************************主函数******************************/ //主要调用函数用来实现功能
int main()
{
show_text(); //显示全文函数
cout << endl;
input(); // 输入函数
return 0;
}
/****************************查询函数*****************************/ //用来查询用户输入的单词
void TLink::Insert(char *Item)
{
int flag = 0;
Node* temp; //新建一个链表来接收数据
temp = new Node;
int i = 0;
while( Item[i] != '\0' )
{
temp -> words[i] = Item[i];
++ i;
}
temp -> num = i;
temp -> words[i] = '\0';
Node* ptrr = NULL;
ptrr = link.gethead();
while( ptrr != NULL )
{
if( ptrr -> num == temp -> num )
{
int n;
for( n = 0; n < i; ++ n )
if( A_to_a( ptrr -> words[n] ) != A_to_a( Item[n] ) ) //对他们进行比较
break;
if( n == i ) //如果找到相等的单词
{
flag = 1;
break;
}
}
ptrr = ptrr -> next;
}
if( flag != 1 )
{
temp -> ptr = NULL;
temp -> next = NULL;
Node* Temp = head;
if( head == NULL )
{
head = temp;
}
else
{
while( Temp -> next != NULL )
Temp = Temp -> next;
Temp -> next = temp;
}
}
else
delete temp; //释放链表
}
/************************大写转化成小写**********************/ //将大些转化成小写,避免开头或特殊单词
char A_to_a( char alp )
{
if( ( alp >= 'A' ) && ( alp <= 'Z' ) )
alp = alp + 32;
return alp;
}
/************************统计频率和位置*******************/
void TLink::calcute(char *szFile, int size)
{
int i = 0; //记录已搜索过的字符数-1
int col = 1; //列标
int row = 0; //行标
int count; //记录空格数-1
Node* ptrr = NULL;
while( i < size )
{
ptrr = link.gethead();
int j = 0;//对每个单词长度计数
while( ( szFile[i] >= 'a' && szFile[i] <= 'z' ) || ( szFile[i] >= 'A' && szFile[i] <= 'Z' ) )
{
++ i;
++ j;
}
while( ptrr != NULL )
{
if( ptrr -> num == j )
{
int n;
for( n = 0; n <= j; ++ n )
if( A_to_a( ptrr -> words[n] ) != A_to_a( szFile[i - j + n] ) )
break;
if( n == j )
{
node* temp;
temp = new node;
temp -> col = col;
temp -> row = row;
temp -> next = NULL;
node* Temp = ptrr -> ptr;
if( ptrr -> ptr == NULL )
{
ptrr -> ptr = temp;
}
else
{
while( Temp -> next != NULL )
Temp = Temp -> next;
Temp -> next = temp;
}
} //插入行数
}
ptrr = ptrr -> next;
}
if( szFile[i] == ' ' || szFile[i] == '\n' )
{
count = -1;
while( szFile[i] == ' ' )
{
++ i; //设置列数
++ row;//行的单词个数加
++ count;//单词之间空格-1
}
row = row - count;
if( szFile[i] == '\n' )
{
++ col; //列遇到换行累加
++ i;
row = 0;//单词的行个数清零
}
}
else
++ i;
}
cout << endl;
}
/*************************获取链表头******************/ Node* TLink::gethead()
{
return head;
}
/************************窗口显示*************************/ //用来显示用户的输入与输出用户所需要的信息
void showwindow()
{
Node* curptr = link.gethead();
while( curptr != NULL )
{
int word_num = 0;
for( int k = 0; curptr -> words[k] != '\0'; ++ k ) cout << curptr -> words[k];
cout << endl;
if( curptr -> ptr == NULL )
cout << "没有该词,或输入不正确!" << endl;
else
while( curptr -> ptr != NULL )
{
cout << "(";
cout << curptr -> ptr -> col ; //显示行数
cout << ",";
cout << curptr -> ptr -> row ; //显示列数
cout << ")";
cout << ' ';
curptr -> ptr = curptr -> ptr -> next;
word_num ++; //统计次数
}
cout << endl;
cout << "该单词共出现" << word_num << "次!" << endl;
curptr = curptr -> next;
}
}
/************************显示全文***************************/ //打开文件并输出TXT文件中的信息
void show_text()
{
ifstream fin; //流
fin.open("D:\\english.txt"); //打开文件
if (fin.fail())
{
cout<<"Input file opening failed.\n";
exit(1);
}
char next; //获取文件中的字符
fin.get(next);
while (! fin.eof()) //判断是否到文件尾
{
szFile[i] = next; //赋予szFile
++ i;
fin.get(next);
} //将整个文件的内容赋给szFile
szFile[i] = '\0'; //尾置空
for( int k = 0; k < i; ++ k )
cout << szFile[k]; //输出文件内容
cout << "*****Total number :" << i << endl;
cout << "********************************************" << endl;
}
/***************************输入函数************************/
//窗口录入用户输入信息给出相应的操作
void input()
{
char Item[40]; //暂存数组
char in; //接受输入字符
char ans; //判断是否重新开始
do{
if( link.gethead() != NULL )
link.~TLink(); //调用析构
cout << "请输入要统计的单词,单词之间用逗号隔开(输入@键结束,本程序忽略空格):" << endl;
cin >> in;
int flag = 1; //用来判断是否输入结束
while( true )
{
if( in == '@' )
break;
int m = 0;
while( in != ',' )
{
Item[m] = in;
++ m;
cin >> in;
if( in == '@' )
{
flag = 0;
break;
}
}
Item[m] = '\0'; //将暂存数据的字符置空
link.Insert( Item );
if( flag == 0 )
break;
cin >> in;
}
if( link.gethead() == NULL )
cout << "没有插入任何单词!" << endl;
else
{
link.calcute( szFile, i );
showwindow();
}
cout << "是否继续?(Y/y or N/n):";
cin >> ans;
}while( ( ans != 'n' ) && ( ans != 'N' ) ); //判断
}
5.系统测试
5.1 实现环境
硬件平台:安装有windows系统,
操作系统和版本:Microsoft visual vc++6.0
5.2 语言选择
C++语言
5.3 测试文件
D:\english.txt
Extravagant Spending on College Campus
According to a survey, in recent years the monthly expenditure of
a college student has been on the sharp rise. Many college students spend
money like water and have no concept of thrift in their mind. They take it for granted that they spend money from their parents before they enter into the society. This extravagant spending is mainly caused by the following factors.
First of all, nowadays most of students are the only children of their families. They are the apple in their family’s eyes and naturally get more care and pocket money. Secondly, with the improvement of living standard, parents can afford higher expenditure of their children. Thirdly, some students like to pursue fashion and trends, which tends to need more money. Finally, campus love is also a possible factor causing extravagant spending.
From my point of view, a college student, as a pure consumer, should learn to be thrifty. We should limit our expenditure on daily necessities but not buy whatever we want regardless of their prices. The habit of thrift can help us form right values and is favorable to our future development.
5.4测试分析
5.4.1运行程序初始界面
图5 运行程序初始界面图
5.4.2输入单词“of”查询结果
图6 输入一个单词查询结果5.4.3输入单词“of”和“student”查询结果
图7 输入两个单词显示结果5.4.4输入“tomorrow”显示结果
图8 输入文中未出现单词显示结果
5.4.5输入“n”推出程序
图9 退出程序
总结
在本次课程设计中感受到自己也可以编写小程序让单词统计变得如此简单,同时再次体会了链表在数据结构中的重要作用,通过查阅书籍与网上查询了解了链表的更多使用技巧,进一步夯实了以后编程的能力。

致谢
在这次课程设计中学到了很多在课堂上没有学到的东西,首先感谢我的老师在上机时对我的耐心指导和帮助,在我编写的程序难以运行满意是老师总是能够给我充分的帮助,启发我成功排除错误,少走了不少弯路;其次我要感谢学校给提供给我们足够的实验环境与器材,同时配备了优秀的指导老师让我们在轻松愉快的环境中学习与实验。

在这次实验中可谓是让我受益匪浅,学得轻松,学得开心,学得满足。

参考文献
[1]谭浩强等.C语言程序设计教程.高等教育出版社.2005
[2]李建学等.数据结构课程设计案例精编(用C/C++描述).清华大学出版.2007-2-1
[3]严蔚敏等.数据结构(C语言版).清华大学出版社.2003-1
#include<iostream>
#include<fstream>
#include<cstdlib>
#include "source.h"
using namespace std;
TLink link;
int i=0;
char szFile[2000]; //定义一个足够长度的字符
/****************************主函数******************************/
int main()
{
show_text(); //显示全文函数
cout << endl;
input(); //输入函数
return 0;
}
/****************************查询函数*****************************/
void TLink::Insert(char *Item)
{
int flag = 0; //监控是否相等
Node* temp;
temp = new Node;
int i = 0;
while( Item[i] != '\0' )
{
temp -> words[i] = Item[i];
++ i;
}
temp -> num = i;
temp -> words[i] = '\0'; //将录入的单词赋予word
Node* ptrr = NULL;
ptrr = link.gethead();
while( ptrr != NULL )
{
if( ptrr -> num == temp -> num )
{
int n;
for( n = 0; n < i; ++ n ) //循环比较
if( A_to_a( ptrr -> words[n] ) != A_to_a( Item[n] ) )
break;
if( n == i ) //如果相等
{
flag = 1;
break;
}
}
ptrr = ptrr -> next;
}
if( flag != 1 )
{
temp -> ptr = NULL;
temp -> next = NULL;
Node* Temp = head;
if( head == NULL )
{
head = temp;
}
else
{
while( Temp -> next != NULL ) Temp = Temp -> next;
Temp -> next = temp;
}
}
else
delete temp;
}
/************************大写转化成小写
*******************************/
char A_to_a( char alp )
{
if( ( alp >= 'A' ) && ( alp <= 'Z' ) )
alp = alp + 32;
return alp;
}
/************************统计频率和位置******************************/
void TLink::calcute(char *szFile, int size)
{
int i = 0; //记录已搜索过的字符数-1
int col = 1; //列标
int row = 0; //行标
int count; //记录空格数-1
Node* ptrr = NULL;
while( i < size )
{
ptrr = link.gethead();
int j = 0; //对每个单词长度计数
while( ( szFile[i] >= 'a' && szFile[i] <= 'z' ) || ( szFile[i] >= 'A' && szFile[i] <= 'Z' ) )
{
++ i;
++ j;
}
while( ptrr != NULL )
{
if( ptrr -> num == j )
{
int n;
for( n = 0; n <= j; ++ n )
if( A_to_a( ptrr -> words[n] ) != A_to_a( szFile[i - j + n] ) )
break;
if( n == j ) //如果相等
{
node* temp;
temp = new node;
temp -> col = col;
temp -> row = row;
temp -> next = NULL;
node* Temp = ptrr -> ptr;
if( ptrr -> ptr == NULL )
{
ptrr -> ptr = temp;
}
else
{
while( Temp -> next != NULL )
Temp = Temp -> next;
Temp -> next = temp;
}
} //插入行数
}
ptrr = ptrr -> next;
}
if( szFile[i] == ' ' || szFile[i] == '\n' )
{
count = -1;
while( szFile[i] == ' ' )
{
++ i; //设置列数
++ row;//行的单词个数加
++ count;//单词之间空格-1
}
row = row - count;
if( szFile[i] == '\n' )
{
++ col; //列遇到换行累加
++ i;
row = 0; //单词的行个数清零
}
}
else
++ i;
}
cout << endl;
}
/*************************获取链表头********************************/
Node* TLink::gethead()
{
return head;
}
/************************窗口显示*************************/
void showwindow()
{
Node* curptr = link.gethead();
while( curptr != NULL )
{
int word_num = 0;
for( int k = 0; curptr -> words[k] != '\0'; ++ k )
cout << curptr -> words[k];
cout << endl;
if( curptr -> ptr == NULL )
cout << "没有该词,或输入不正确!" << endl;
else
while( curptr -> ptr != NULL )
{
cout << "(";
cout << curptr -> ptr -> col ; //显示行数
cout << ",";
cout << curptr -> ptr -> row ; //显示列数
cout << ")";
cout << ' ';
curptr -> ptr = curptr -> ptr -> next;
word_num ++; //统计次数
}
cout << endl;
cout << "该单词共出现" << word_num << "次!" << endl;
curptr = curptr -> next;
}
}
/************************显示全文*****************************/
void show_text()
{
ifstream fin; //流
fin.open("D:\\english.txt"); //打开文件
if (fin.fail())
{
cout<<"Input file opening failed.\n";
exit(1);
}
char next; //获取文件中的字符
fin.get(next);
while (! fin.eof()) //判断是否到文件尾
{
szFile[i] = next; //赋予szFile
++ i;
fin.get(next);
} //将整个文件的内容赋给szFile
szFile[i] = '\0'; //尾置空
for( int k = 0; k < i; ++ k )
cout << szFile[k]; //输出文件内容
cout << "*****Total number :" << i << endl;
cout <<
"************************************************************************* **" << endl;
}
/***************************输入函数
***********************************/
void input()
{
char Item[40]; //暂存数组
char in; //接受输入字符
char ans; //判断是否重新开始
do{
if( link.gethead() != NULL )
link.~TLink(); //调用析构
cout << "请输入要统计的单词,单词之间用逗号隔开(输入@键结束,本程序忽略空格):" << endl;
cin >> in;
int flag = 1; //用来判断是否输入结束
while( true )
{
if( in == '@' )
break;
int m = 0;
while( in != ',' )
{
Item[m] = in;
++ m;
cin >> in;
if( in == '@' )
{
flag = 0;
break;
}
}
Item[m] = '\0'; //将暂存数据的字符置空
link.Insert( Item ); //相当于把一个单词传过去if( flag == 0 )
break;
cin >> in;
}
if( link.gethead() == NULL )
cout << "没有插入任何单词!" << endl;
else
{
- 37 -
link.calcute( szFile, i );
showwindow();
}
cout << "是否继续?(Y/y or N/n):";
cin >> ans;
}while( ( ans != 'n' ) && ( ans != 'N' ) ); //判断}
- 38 -。

相关文档
最新文档