问题描述:对于一篇给定的英文文章,分别利用线性表或二叉排序树来实现单词频率的统计,实现低频词的过滤,并比较两种方法的效率。
来这看的估计都是想搞数据结构课程设计吧,不知道有没有跟我同一个老师的,拿走后记得修改一下下
注意单步执行需要按顺序,不想这样的话可以自己修改函数
功能要求:
1. 读取英文文章文件(InFile.txt),识别其中的单词。
2. 分别利用线性表和二叉排序树构建单词的存储结构。当识别出一个单词后,若线性表或者二叉排序树中没有该单词,则在适当的位置上添加该单词;若该单词已经被识别,则增加其出现的频率。
3. 统计结束后,删除出现频率低于五次的单词,并显示该单词和其出现频率。
4.其余单词及其出现频率按照从高到低的次序输出到文件中(OutFile.txt),同时输出用两种方法完成该工作所用的时间。
5.计算查找表的ASL值,分析比较两种方法的效率。
6.系统运行后主菜单如下:
当选择1后进入以下界面:
其中选择2时显示利用线性表来实现所有功能所用的时间。
当在主菜单选择2二叉排序树后,进入的界面与上图类同。
实现提示:
1、在统计的过程中,分词时可以利用空格或者标点符号作为划分单词依据,文章中默认只包含英文单词和标点符号。
2、对单词进行排序时,是按照字母序进行的,每个结点还应包含该单词出现的频率。
3、存储结构的定义
直接贴完整代码了
代码太长了没办法一次性粘贴,分成了四部分
如果有什么问题,欢迎指正
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <time.h>
#include <math.h>
#include <string.h>
#include <windows.h>
#include <iomanip>
using namespace std;
ofstream oF;
ifstream iF;
string fn;
typedef struct Node // 结点结构
{
string data;
int count;
struct Node *next;
struct Node *lchild, *rchild;
} * BSTNode, *BSTree, *Link, *Linklist;
typedef struct Lnode
{
BSTree tree[200];
int top;
} Lnode, link; //结构体,节点=0;
link s;
void InitStack() //栈初始化
{
s.top = 0;
}
int StackEmpty() //判断栈是否为空栈
{
if (s.top == 0)
return 1;
else
return 0;
}
void Push(BSTree t) //入栈
{
s.top++;
s.tree[s.top] = t;
}
void Pop() //出栈
{
s.top--;
}
int com(string a, string b) //验证a与b的大小(按照字母顺序)
{
int i, j;
for (i = 0; i < a.length(), i < b.length(); i++)
{
if (a[i] > b[i])
return 0;
if (a[i] < b[i])
return 1;
}
if (i == a.length() - 2)
return 1;
else
return 0;
}
void Linkinsert(Linklist &L, string a)//在当前位置的后一位插入
{
Link o = new Node;
o->data = a;
o->count = 1;
o->next = L->next;
L->next = o;
}
void link_read(Linklist &L)//从文件中读取文章,并将单词按字母顺序排列
{
L = new Node;
L->next = NULL;
Link p, q;
string l, w;
char t;
iF.open(fn);
while (iF.get(t))
{
if (t >= 'a' && t <= 'z' || t >= 'A' && t <= 'Z' || t == '\'')//一个字符一个字符读入
{
if (t >= 'A' && t <= 'Z')
t += 32;
w += t;
}
else
{
if (w == "")
continue;
q = L;
p = q->next;
while (p)
{
if (p->data == w)
{
w = "";
p->count++;
break;
}
q = p;
p = p->next;
}
if (w != "")
{
q = L;
p = q->next;
while (p)
{
if (com(w, p->data))
break;
q = p;
p = q->next;
}
Linkinsert(q, w);
w = "";
}
}
}
iF.close();
}
void linkshow(Linklist l)//输出链表
{
Link p;
int a = 0;
p = l->next;
while (p)
{
a++;
cout.setf(ios::left);
cout << setw(15) << p->data << " " << setw(2) << p->count << " ";
cout.unsetf(ios::left);
if (a % 3 == 0)
cout << endl;
p = p->next;
}
cout << endl;
return;
}
void link_delete(Linklist &l)//删除低频词汇
{
cout << "低频词汇如下所示:\n";
int a = 0;
Link p, q;
q = l;
p = q->next;
while (p)
{
if (p->count < 5)
{
a++;
cout.setf(ios::left);
cout << setw(15) << p->data << " " << setw(2) << p->count << " ";
cout.unsetf(ios::left);
Link o = p;
q->next = o->next;
free(o);
p = q->next;
if (a % 3 == 0)
cout << endl;
continue;
}
q = p;
p = q->next;
}
cout << endl;
}
void Linksort(Linklist &l)//按频率给数据排序
{
Link p, q, r;
r = l;
while (r->next->next)
{
q = r->next;
p = q->next;
while (p)
{
if (p->count > r->next->count)
{
q->next = p->next;
p->next = r->next;
r->next = p;
p = q->next;
continue;
}
q = p;
p = p->next;
}
r = r->next;
}
}
void linkwrite(Linklist L)//写入文件
{
oF.open("Link_OutFile.txt");
oF.setf(ios::left);
oF << "高频单词及其频率如下:" << endl;
Link p;
p = L->next;
while (p)
{
oF.setf(ios::left);
oF << setw(15) << p->data << " " << setw(2) << p->count << endl;
oF.unsetf(ios::left);
p = p->next;
}
oF.close();
return;
}
void linkASL(Linklist L)//求出链表的ASL值
{
int a = 0, b = 0;
Link p;
p = L->next;
while (p)
{
a++;
b += a;
p = p->next;
}
cout << "链表的ASL值为:" << b * 1.0 / a << endl;
return;
}
void BSTInsert(BSTree &T, string e)//二叉排序树按字母顺序插入数据
{
if (!T)
{
BSTNode o = new Node;
o->data = e;
o->count = 1;
T = o;
T->lchild = NULL;
T->rchild = NULL;
}
else if (T->data == e)
{
T->count++;
return;
}
else if (!com(T->data, e))
BSTInsert(T->lchild, e);
else
BSTInsert(T->rchild, e);
}
void BSTread(BSTree &T)//从文件中读取文章到二叉树
{
T = new Node;
T = NULL;
Link a = new Node;
string w;
char t;
iF.open(fn);
while (iF.get(t))
{
if (t >= 'a' && t <= 'z' || t >= 'A' && t <= 'Z' || t == '\'')
{
if (t >= 'A' && t <= 'Z')
t += 32;
w += t;
}
else
{
if (w == "")
continue;
BSTInsert(T, w);
w = "";
}
}
iF.close();
}
void BSTwrite(BSTree T)//将二叉树按照中序写入文件
{
int a = 0;
InitStack();
BSTree t = T;
oF.open("BST_OutFile.txt");
oF.setf(ios::left);
oF << "高频单词及其频率如下:" << endl;
oF.setf(ios::left);
while (t || !StackEmpty())
{
while (t)
{
Push(t);
t = t->lchild;
}
if (!StackEmpty())
{
t = s.tree[s.top];
Pop();
oF << setw(15) << t->data << " " << setw(2) << t->count << endl;
t = t->rchild;
}
}
oF.close();
oF.unsetf(ios::left);
}
void BSTshow(BSTree T) //中序输出
{
int a = 0;
InitStack();
BSTree t = T;
while (t || !StackEmpty())
{
while (t)
{
Push(t);
t = t->lchild;
}
if (!StackEmpty())
{
t = s.tree[s.top];
Pop();
cout.setf(ios::left);
cout << setw(15) << t->data << " " << setw(2) << t->count << " ";
cout.unsetf(ios::left);
a++;
if (a % 3 == 0)
cout << endl;
t = t->rchild;
}
}
cout << endl;
}
void BSTorder(BSTree &T, BSTNode e)//按出现频率顺序插入二叉树中
{
if (!T)
{
BSTNode o = new Node;
o->data = e->data;
o->count = e->count;
T = o;
T->lchild = NULL;
T->rchild = NULL;
return;
}
if (T->count < e->count)
{
BSTorder(T->lchild, e);
}
if (T->count > e->count)
{
BSTorder(T->rchild, e);
}
if (T->count == e->count)
{
if (com(T->data, e->data))
{
BSTorder(T->rchild, e);
}
else
{
BSTorder(T->lchild, e);
}
}
}
void BSTDelete(BSTree &T)//删除低频词汇
{
BSTree o = new Node;
o = NULL;
int a = 0;
InitStack();
BSTree t = T;
while (t || !StackEmpty())
{
while (t)
{
Push(t);
t = t->lchild;
}
if (!StackEmpty())
{
t = s.tree[s.top];
Pop();
if (t->count < 5)
{
cout.setf(ios::left);
cout << setw(15) << t->data << " " << setw(2) << t->count << " ";
cout.unsetf(ios::left);
a++;
if (a % 3 == 0)
cout << endl;
t = t->rchild;
}
else
{
BSTorder(o, t);
t = t->rchild;
}
}
}
T = o;
cout << endl;
}
int BSTnodecnt(BSTree T)//计算二叉树总结点数
{
int d = 0;
if (!T)
return 0;
else
{
d = 1 + BSTnodecnt(T->lchild) + BSTnodecnt(T->rchild);
}
return d;
}
int BSTasl(BSTree t, int d)//计算二叉树总权值
{
d++;
int a = d;
if (t->lchild)
d += BSTasl(t->lchild, a);
if (t->rchild)
d += BSTasl(t->rchild, a);
return d;
}
void BSTaslplus(BSTree T)//返回二叉树ASL值
{
cout << "该二叉排序树ASL值为:" << BSTasl(T, 0) * 1.0 / BSTnodecnt(T) << endl;
return;
}
void ui1()
{
cout << "1、线性表" << endl;
cout << "2、二叉排序树" << endl;
cout << "3、退出系统" << endl;
cout << "请输入你需要的服务,输入数字(1-3):";
return;
}
void ui2()
{
cout << "1、连续执行完毕" << endl;
cout << "2、显示执行时间" << endl;
cout << "3、单步执行:识别并统计单词" << endl;
cout << "4、单步执行:删除并显示出低频率单词" << endl;
cout << "5、单步执行:输出其余单词及其频率" << endl;
cout << "6、单步执行:计算并输出ASL值" << endl;
cout << "7、返回主菜单" << endl;
return;
}
int main()
{
cout << "请输入文件名(不包含后缀,注意大小写):";
while (1)
{
cin >> fn;
fn += ".txt";
iF.open(fn);
if (!iF.is_open())
{
cout << "请检查文件名是否输入正确,或文件是否与程序放在同一目录!\n\n请重新输入:";
}
else
{
iF.close();
break;
}
}
Linklist Li;
BSTree Tr;
int flag1, flag2, t;
while (1)
{
system("cls");
ui1();
cin >> flag1;
switch (flag1)
{
case 1:
system("cls");
while (1)
{
ui2();
cin >> flag2;
if (flag2 == 1)
{
system("cls");
link_read(Li);
cout << "所有单词及其频率如下:\n";
linkshow(Li);
link_delete(Li);
Linksort(Li);
cout << "高频词汇如下所示:\n";
linkshow(Li);
cout<<"已输出至本程序目录下\n";
linkwrite(Li);
linkASL(Li);
}
if (flag2 == 2)
{
DWORD start, end;
start = GetTickCount();
link_read(Li);
link_delete(Li);
Linksort(Li);
linkwrite(Li);
linkASL(Li);
end = GetTickCount();
t = end - start;
system("cls");
cout << "共耗时" << t << "ms\n";
}
if (flag2 == 3)
{
system("cls");
cout << "所有单词及其频率如下:\n";
link_read(Li);
linkshow(Li);
}
if (flag2 == 4)
{
system("cls");
link_delete(Li);
}
if (flag2 == 5)
{
system("cls");
cout << "高频单词及其频率如下:\n";
Linksort(Li);
linkshow(Li);
cout<<"已输出至本程序目录下\n";
}
if (flag2 == 6)
{
system("cls");
linkASL(Li);
}
if (flag2 == 7)
break;
}
break;
case 2:
system("cls");
while (1)
{
ui2();
cin >> flag2;
if (flag2 == 1)
{
system("cls");
BSTread(Tr);
cout << "所有词汇及其频率如下:\n";
BSTshow(Tr);
cout << "低频词汇及其频率如下:\n";
BSTDelete(Tr);
cout << "高频词汇及其频率如下:\n";
BSTshow(Tr);
cout<<"已输出至本程序目录下\n";
BSTwrite(Tr);
BSTaslplus(Tr);
}
if (flag2 == 2)
{
DWORD start, end;
start = GetTickCount();
BSTread(Tr);
BSTshow(Tr);
BSTDelete(Tr);
BSTwrite(Tr);
BSTaslplus(Tr);
system("cls");
end = GetTickCount();
t = end - start;
cout << "共耗时" << t << "ms\n";
}
if (flag2 == 3)
{
system("cls");
cout << "所有词汇及其频率如下:\n";
BSTread(Tr);
BSTshow(Tr);
}
if (flag2 == 4)
{
system("cls");
cout << "低频词汇及其频率如下:\n";
BSTDelete(Tr);
}
if (flag2 == 5)
{
system("cls");
cout << "高频词汇及其频率如下:\n";
BSTshow(Tr);
cout<<"已输出至本程序目录下\n";
BSTwrite(Tr);
}
if (flag2 == 6)
{
system("cls");
BSTaslplus(Tr);
}
if (flag2 == 7)
break;
}
break;
case 3:
return 0;
}
}
}