基于线性表和二叉排序树的低频词过滤系统的设计与实现
此报告并不是很好。看看就可
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<time.h>
#include<string.h>
#include<iostream>
using namespace std;
/******************************定义的函数与全局变量****************************/
int a;//用于选判断选择什么服务
void screem();//主屏幕
void screem2();//第二选项屏幕
/***************************线性表所用函数**************************************/
typedef struct node1//单链表节点
{
char data[20];
int count;
struct node1 *next;
}LNode,*LinkList;
void linear();//线性表
void InitList();//构建一个空的线性表
void time1();//线性表计算执行时间
void distinguish_count1();//线性表第三步识别并统计单词
void InsertList(LinkList &L,char *a);//先将每一元素存入线性链表中,然后统计个数
void sort_slist(LinkList &L);//比较出现的频率和交换
void exchange1(LinkList x,LinkList y);//交换顺序
void print_1(LinkList &L);//线性表输出单词和出现的频率
void delete1();//线性表删除低频单词
void out1();//线性表输出高频单词及其频率
void ASL1();//线性表计算ASL
void allfinish1();//线性表一次性全部执行
/*********************************线性表********************************************************/
void InitList(LinkList &L)//构建一个空的线性表
{
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
}
void linear()//线性表
{
a=0;
screem2();
cin>>a;
while((a==1||a==2||a==3||a==4||a==5||a==6||a==7)==0)
{
cout<<"输入错误,请重新输入:"<<endl;
cin>>a;
}
switch (a)
{
case 1:
allfinish1();
linear();
break;
case 2:
time1();
linear();
break;
case 3:
distinguish_count1();
linear();
break;
case 4:
delete1();
linear();
break;
case 5:
out1();
linear();
break;
case 6:
ASL1();
linear();
break;
case 7:
break;
}
}
void allfinish1()//除时间外,一次性全部执行
{
distinguish_count1();
delete1();
out1();
ASL1();
}
void time1()//计算执行时间
{
double star,finish,time;
star=(double)clock();//获取当前时间
distinguish_count1();
delete1();
out1();
ASL1();
finish=(double)clock();//获取结束时间
time=finish-star;
printf("执行时间:%.2f ms\n",time);//得到的是运行for语句所用的时间,时间单位了毫秒
}
void distinguish_count1()//识别并统计单词
{
FILE *in;
char arr[20],c;
int i;
LinkList L;
InitList(L);//引用函数创建空线性表
in=fopen("f1.txt","r");//打开输入文件
while(!feof(in))//直到碰见文件结束符结束循环
{
i=0;
memset(arr,0,sizeof(arr));//内存空间初始化
while((c=fgetc(in))!=EOF&&(c==','||c=='.'||c=='!'||c=='?'||c==' '||c=='('||c==')'||c=='\n')==0)
{
arr[i++]=c;
}//让数组保存字母
if(arr[0])InsertList(L,arr);
}
sort_slist(L);
print_1(L);
fclose(in);//关闭文件
}
void InsertList(LinkList &L,char *arr)//先将每一元素存入线性链表中,然后统计个数
{
int flag=0;
LinkList P;
LinkList Q;
Q=L->next;
while(Q!=NULL)
{
if(stricmp(arr,Q->data)==0)//比较单词是否相同
{
Q->count++;//相同count+1
flag=1;
break;
}
Q=Q->next;
}
if(flag==0)//头插法插入单词
{
P=(LinkList)malloc(sizeof(LNode));
strcpy(P->data,arr);
P->count=1;
P->next=L->next;
L->next=P;
}
}
void sort_slist(LinkList &L)//比较出现的频率和交换
{
LinkList p,q,temp;
p=L->next;
while(p)
{
q=p->next;
while(q)
{
if(p->count<q->count)//比较单词出现的次数
{
exchange1(p,q);//交换顺序,频率高的在前
}
else
q=q->next;
}
p=p->next;
}
}
void exchange1(LinkList p,LinkList q)//交换顺序
{
char arr[20];
int b;
strcpy(arr,p->data);
b=p->count;
strcpy(p->data,q->data);
p->count=q->count;
strcpy(q->data,arr);
q->count=b;
}
void print_1(LinkList &L)//输出单词出现的频率
{
LinkList P;
P=L->next;
cout<<" "<<"单词"<<" "<<"个数统计"<<endl;
while(P!=NULL)
{
printf(" %-20s",P->data);
cout<<" ";
cout<<P->count<<endl;
P=P->next;
}
}
void delete1()//删除低频单词
{
FILE *in,*out;
LinkList L,P,Q;
char a[20],c;
InitList(L);
in=fopen("f1.txt","r");//打开输入文件
while(!feof(in))//直到碰见文件结束符结束循环
{
int i=0;
memset(a,0,sizeof(a));//内存空间初始化
while((c=fgetc(in))!=EOF&&(c==','||c=='.'||c=='!'||c=='?'||c==' '||c=='('||c==')'||c=='\n')==0)
{
a[i++]=c;
}//让数组保存字母
if(a[0])InsertList(L,a);
}//建立链表
sort_slist(L);
fclose(in);
printf("删除低频词汇\n");
out=fopen("f2.txt","w+");//建立输出文件
P=L->next;
while(P!=NULL&&P->count>=5)
{
P=P->next;
}
while(P!=NULL)
{
Q=P;
P=P->next;
printf("删除节点: %-20s",Q->data);
cout<<" ";
cout<<Q->count<<endl;
free(Q);//释放空间,删除结点
}
fclose(out);
}
void out1()//输出高频单词及其频率
{
FILE *in,*out;
int j=1;
char a[20],c;
LinkList L,P,Q;
InitList(L);
in=fopen("f1.txt","r");//打开输入文件
while(!feof(in))//直到碰见文件结束符结束循环
{
int i=0;
memset(a,0,sizeof(a));
while((c=fgetc(in))!=EOF&&!(c==','||c=='.'||c=='!'||c=='?'||c==' '||c=='('||c==')'))
{
a[i++]=c;
}
if(a[0])
{
InsertList(L,a);
}
}
sort_slist(L);
fclose(in);//关闭文件
out=fopen("f2.txt","w+");//建立输出文件
P=L->next;
printf("删除低频率单词后\n单词 个数统计\n");
while(P&&P->count>=5)
{
printf("%-20s",P->data);
cout<<" ";
cout<<P->count<<endl;
fprintf(out,"%s(%d)\t",P->data,P->count);
P=P->next;
}
cout<<"写入文件f2.txt成功"<<endl;
fclose(out);//关闭文件
}
void ASL1()//计算ASL
{
FILE *in;
int sum=0;
char a[20],c;
LinkList L,p;
InitList(L);
in=fopen("f1.txt","r");//打开输入文件
double ASL;
while(!feof(in))//直到碰见文件结束符结束循环
{
int i=0;
memset(a,0,sizeof(a));//内存空间初始化
while((c=fgetc(in))!=EOF&&(c==','||c=='.'||c=='!'||c=='?'||c==' '||c=='('||c==')'||c=='\n')==0)
{
a[i++]=c;
}//让数组保存字母
if(a[0])InsertList(L,a);
}
p=L->next;
while(p)
{
sum++;
p=p->next;
}
cout<<"单词总个数:"<<sum<<endl;
fclose(in);//关闭文件
ASL=(double)(sum+1)/2.0;
printf("ASL = %.2f \n",ASL);
}
/*********************************二叉排序树所定义使用函数*****************************************/
typedef struct node2//排序二叉树节点
{
char data[20];
int count;
struct node2* left;
struct node2* right;
}TNode, *Ttree;
void allfinish2();//一次性全部执行
void time2();//计算执行时间
void distinguish_count2();//二叉排序树第三步识别并统计单词
void add_Tree(Ttree &T,char *arr);//先将每一元素存入树中,然后统计个数
void print2(Ttree T);//中序遍历二叉排序树,得到有序序列
void delete2();//显示低频单词并删除
void newTtree1(Ttree T);//中序遍历二叉排序树,得到有序序列
void add_Tree2(Ttree &nT,Ttree T);//中序遍历二叉排序树,得到有序序列
void newTtree2(Ttree T);//中序遍历二叉排序树,得到有序序列
void out2();//输出高频单词
/**************************************二叉排序树*********************************************/
Ttree T,nT;
void Tree()//二叉排序树
{
a=0;
screem2();//第二主屏幕
scanf("%d",&a);
while((a==1||a==2||a==3||a==4||a==5||a==6||a==7)==0)
{
cout<<"输入错误,请重新输入:";
cin>>a;
}
switch (a)
{
case 1:
allfinish2();
Tree();
break;
case 2:
time2();
Tree();
break;
case 3:
distinguish_count2();
Tree();
break;
case 4:
delete2();
Tree();
break;
case 5:
out2();
Tree();
break;
case 6:
Tree();
break;
case 7:
break;
}
}
void allfinish2()
{
distinguish_count2();
delete2();
out2();
}
void time2()
{
double star,finish;
star=(double)clock();//获取当前时间
distinguish_count2();
delete2();
out2();
finish=(double)clock();//获取结束时间
printf("执行时间:%.2f ms\n",(finish-star));
//得到的是运行for语句所用的时间,时间单位了毫秒
}
void distinguish_count2()//二叉排序树第三步识别并统计单词
{
FILE *in;
T=NULL;
in=fopen("f1.txt","r");//打开输入文件
char arr[20],c;
while(!feof(in))//直到碰见文件结束符结束循环
{
int i=0;
memset(arr,0,sizeof(arr));
while((c=fgetc(in))!=EOF&&(c==','||c=='.'||c=='!'||c=='?'||c==' '||c=='('||c==')'||c=='\n')==0)
{
arr[i++]=c;
}
if(arr[0])
add_Tree(T,arr);
}
cout<<"单词 个数统计"<<endl;
print2(T);//中序遍历二叉排序树
}
void add_Tree(Ttree &T,char *arr)//先将每一元素存入树中,然后统计个数
{
if (T==NULL)
{
T=(Ttree)malloc(sizeof(TNode));
strcpy(T->data,arr);
T->left=NULL;
T->right=NULL;
T->count=1;
}
else
{ //比较字母的大小(ASCII码)
if(stricmp(arr,T->data)<0)//小的移到左边
{
add_Tree(T->left,arr);
}
else if(stricmp(arr,T->data)==0)//相同频率count+1
{
T->count++;
}
else
{
add_Tree(T->right,arr);//大的移到右边
}
}
}
void print2(Ttree T)//中序遍历二叉排序树,得到有序序列
{
if(T)
{
print2(T->left);
printf("%-20s ",T->data);
cout<<T->count<<endl;
print2(T->right);
}
}
void delete2()//显示低频单词并删除
{
FILE *in;
T=NULL;
in=fopen("f1.txt","r");//打开输入文件
char arr[20],c;
while(!feof(in))//直到碰见文件结束符结束循环
{
int i=0;
memset(arr,0,sizeof(arr));
while((c=fgetc(in))!=EOF&&(c==','||c=='.'||c=='!'||c=='?'||c==' '||c=='('||c==')'||c=='\n')==0)
{
arr[i++]=c;
}
if(arr[0])
add_Tree(T,arr);
}
cout<<"删除频率小于5的二叉排序树中序遍历"<<endl;
nT=NULL;
newTtree1(T);
cout<<"单词 个数统计"<<endl;
print2(nT);
}
void newTtree1(Ttree T)//中序遍历二叉排序树
{
if(T!=NULL)
{
newTtree1(T->left);//递归
if(T->count<5)
{
add_Tree2(nT,T);
}
newTtree1(T->right);//递归
}
}
void add_Tree2(Ttree &nT,Ttree T)//中序遍历二叉排序树
{
if (nT==NULL)
{
nT=(Ttree)malloc(sizeof(TNode));
strcpy(nT->data,T->data);
nT->count=T->count;
nT->left=NULL;
nT->right=NULL;
}
else
{ //比较字母的大小(ASCII码)
if(stricmp(T->data,nT->data)<0)//小的移到左边
{
add_Tree2(nT->left,T);
}
else
{
add_Tree2(nT->right,T);//大的移到右边
}
}
}
void out2()
{
FILE *in;
T=NULL;
in=fopen("f1.txt","r");//打开输入文件
char arr[20],c;
while(!feof(in))//直到碰见文件结束符结束循环
{
int i=0;
memset(arr,0,sizeof(arr));
while((c=fgetc(in))!=EOF&&(c==','||c=='.'||c=='!'||c=='?'||c==' '||c=='('||c==')'||c=='\n')==0)
{
arr[i++]=c;
}
if(arr[0])
add_Tree(T,arr);
}
cout<<"显示频率大于5的二叉排序树中序遍历"<<endl;
nT=NULL;
newTtree2(T);
cout<<"单词 个数统计"<<endl;
print2(nT);
}
void newTtree2(Ttree T)//中序遍历二叉排序树,得到有序序列
{
if(T!=NULL)
{
newTtree2(T->left);//递归
if(T->count>=5)
{
add_Tree2(nT,T);
}
newTtree2(T->right);//递归
}
}
/***************************************主屏幕******************************************************/
void screem()//主屏幕
{
printf("1、线性表\n");
printf("2、二叉排序树\n");
printf("3、退出系统\n");
printf("请选择你需要的服务,输入数字(1-3)\n");
}
void screem2()//第二主屏幕
{
printf("1、连续执行至完毕\n");
printf("2、显示执行时间\n");
printf("3、单步执行:识别并统计单词\n");
printf("4、单步执行:删除并显示出现频率低单词\n");
printf("5、单步执行:输出其余单词及其频率\n");
printf("6、单步执行计算并输出ASL值\n");
printf("7、返回主菜单\n");
printf("请选择你需要的服务,输入数字(1-7)\n");
}
int main()
{
while(1)
{
screem();
cin>>a;
while(!(a==1||a==2||a==3))
{
cout<<"输入有误,请重新输入"<<endl;
cin>>a;
}
switch(a)
{
case 1:
linear();
break;
case 2:
Tree();
break;
case 3:return 0;
}
}
return 0;
}