#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<ctime>
#include<string>
#include<iostream>
using namespace std;
//显示函数
int a;//用于选判断选择什么服务
void main_menu() //主菜单
{
cout << "1、线性表" << endl;
cout << "2、二叉排序树" << endl;
cout << "3、退出系统 " << endl;
cout << "请选择你需要的服务,输入数字(1-3) " << endl;
}
void sec_menu() //次菜单
{
cout << "1、连续执行至完毕 " << endl;
cout << "2、显示执行时间 " << endl;
cout << "3、单步执行:识别并统计单词 " << endl;
cout << "4、单步执行:删除并显示出现频率低单词 " << endl;
cout << "5、单步执行:输出其余单词及其频率 " << endl;
cout << "6、单步执行计算并输出ASL值 " << endl;
cout << "7、返回主菜单 " << endl;
cout << "请选择你需要的服务,输入数字(1-7) " << endl;
}
//线性表部分
typedef struct Link//单链表节点
{
char data[20];
int count;
struct Link* next;
}LNode, * LinkList;
class Linklist
{
public:
Linklist(){}
void linear(); //线性表
void InitList(LinkList& L); //构建一个空的线性表
void time1(); //线性表计算执行时间
void Count_1(); //线性表第三步识别并统计单词
void InsertList(LinkList& L, char* a); //先将每一元素存入线性链表中,然后统计个数
void sort(LinkList& L); //比较出现的频率和交换
void exchange_List(LinkList x, LinkList y); //交换顺序
void print_List(LinkList& L); //线性表输出单词和出现的频率
void delete_list(); //线性表删除低频单词
void output_List(); //线性表输出高频单词及其频率
void ASL_List(); //线性表计算ASL
void allfinish_List(); //线性表一次性全部执行
};
void Linklist::InitList(LinkList& L)//构建一个空的线性表
{
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
}
void Linklist::linear()//线性表
{
a = 0;
sec_menu();
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:
allfinish_List();
linear();
break;
case 2:
time1();
linear();
break;
case 3:
Count_1();
linear();
break;
case 4:
delete_list();
linear();
break;
case 5:
output_List();
linear();
break;
case 6:
ASL_List();
linear();
break;
case 7:
break;
}
}
void Linklist::allfinish_List()//除时间外,一次性全部执行
{
Count_1();
delete_list();
output_List();
ASL_List();
}
void Linklist::time1()//计算执行时间
{
double star, finish, time;
star = (double)clock(); //获取当前时间
Count_1();
delete_list();
output_List();
ASL_List();
finish = (double)clock(); //获取结束时间
time = finish - star;
printf("执行时间:%.2f ms\n", time); //得到的是运行for语句所用的时间,时间单位了毫秒
}
void Linklist::Count_1() //识别并统计单词
{
FILE* in;
char arr[20], c;
int i;
LinkList L;
InitList(L);//引用函数创建空线性表
in = fopen("Infile.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(L);
print_List(L);
fclose(in); //关闭文件
}
void Linklist::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 Linklist::sort(LinkList& L) //比较出现的频率和交换
{
LinkList p, q, temp;
p = L->next;
while (p)
{
q = p->next;
while (q)
{
if (p->count < q->count) //比较单词出现的次数
{
exchange_List(p, q); //交换顺序,频率高的在前
}
else
q = q->next;
}
p = p->next;
}
}
void Linklist::exchange_List(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 Linklist::print_List(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 Linklist::delete_list() //删除低频单词
{
FILE* in, * out;
LinkList L, P, Q;
char a[20], c;
InitList(L);
in = fopen("Infile.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(L);
fclose(in);
printf("删除低频词汇\n");
out = fopen("输出结果.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 Linklist::output_List() //输出高频单词及其频率
{
FILE* in, * out;
int j = 1;
char a[20], c;
LinkList L, P, Q;
InitList(L);
in = fopen("Infile.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(L);
fclose(in); //关闭文件
out = fopen("输出结果.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 << "写入文件输出结果.txt成功" << endl;
fclose(out); //关闭文件
}
void Linklist::ASL_List() //计算线性表的ASL
{
FILE* in;
int sum = 0;
char a[20], c;
LinkList L, p;
InitList(L);
in = fopen("Infile.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 BSTnode//排序二叉树节点
{
char data[20];
int count; //单词出现频率
struct BSTnode* left; //左指针
struct BSTnode* right; //右指针
}TNode, * Ttree;
class Bitree
{
public:
void allfinish_BTree();//一次性全部执行
void time_BTree();//计算执行时间
void count_BTree();//二叉排序树第三步识别并统计单词
void add_BTree(Ttree& T, char* arr);//先将每一元素存入树中,然后统计个数
void print_BTree(Ttree T);//中序遍历二叉排序树,得到有序序列
void delete_BTree();//显示低频单词并删除
void BTtree_1(Ttree T);
void BTree_3(Ttree& nT, Ttree T);
void BTtree_2(Ttree T);//中序遍历二叉排序树,得到有序序列
void output_BTree();//输出高频单词
void BTree();//二叉排序树
private:
Ttree T, nT;
};
//排序树部分
void Bitree::BTree()//二叉排序树
{
a = 0;
sec_menu();//第二主屏幕
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:
allfinish_BTree();
BTree();
break;
case 2:
time_BTree();
BTree();
break;
case 3:
count_BTree();
BTree();
break;
case 4:
delete_BTree();
BTree();
break;
case 5:
output_BTree();
BTree();
break;
case 6:
BTree();
break;
case 7:
break;
}
}
void Bitree::allfinish_BTree()
{
count_BTree();
delete_BTree();
output_BTree();
}
void Bitree::time_BTree()
{
double star, finish;
star = (double)clock(); //获取当前时间
count_BTree();
delete_BTree();
output_BTree();
finish = (double)clock(); //获取结束时间
printf("执行时间:%.2f ms\n", (finish - star)); //得到的是运行for语句所用的时间,时间单位了毫秒
}
void Bitree::count_BTree() //二叉排序树第三步识别并统计单词
{
FILE* in;
T = NULL;
in = fopen("Infile.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_BTree(T, arr);
}
cout << "单词 个数统计" << endl;
print_BTree(T); //中序遍历二叉排序树
}
void Bitree::add_BTree(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_BTree(T->left, arr);
}
else if (stricmp(arr, T->data) == 0) //相同则频率count+1
{
T->count++;
}
else
{
add_BTree(T->right, arr); //大的移到右边
}
}
}
void Bitree::print_BTree(Ttree T) //中序遍历二叉排序树,得到有序序列
{
if (T)
{
print_BTree(T->left);
printf("%-20s ", T->data);
cout << T->count << endl;
print_BTree(T->right);
}
}
void Bitree::delete_BTree() //显示低频单词并删除
{
FILE* in;
T = NULL;
in = fopen("Infile.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_BTree(T, arr);
}
cout << "删除频率小于5的二叉排序树中序遍历" << endl;
nT = NULL;
BTtree_1(T);
cout << "单词 个数统计" << endl;
print_BTree(nT);
}
void Bitree::BTtree_1(Ttree T) //中序遍历二叉排序树
{
if (T != NULL)
{
BTtree_1(T->left); //递归
if (T->count < 5)
{
BTree_3(nT, T);
}
BTtree_1(T->right); //递归
}
}
void Bitree::BTree_3(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
{
if (stricmp(T->data, nT->data) < 0)
{
BTree_3(nT->left, T);
}
else
{
BTree_3(nT->right, T);
}
}
}
void Bitree::output_BTree()
{
FILE* in;
T = NULL;
in = fopen("Infile.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_BTree(T, arr);
}
cout << "显示频率大于5的二叉排序树中序遍历" << endl;
nT = NULL;
BTtree_2(T);
cout << "单词 个数统计" << endl;
print_BTree(nT);
}
void Bitree::BTtree_2(Ttree T) //中序遍历二叉排序树,得到有序序列
{
if (T != NULL)
{
BTtree_2(T->left);
if (T->count >= 5)
{
BTree_3(nT, T);
}
BTtree_2(T->right);
}
}
int main()
{
Linklist s;
Bitree r;
while (1)
{
main_menu();
cin >> a;
while (!(a == 1 || a == 2 || a == 3))
{
cout << "输入有误,请重新输入" << endl;
cin >> a;
}
switch (a)
{
case 1:
s.linear();
break;
case 2:
r.BTree();
break;
case 3:return 0;
}
}
return 0;
}
基于线性表和二插排序树的低频词过滤系统
最新推荐文章于 2021-12-07 19:23:17 发布