基于线性表和二插排序树的低频词过滤系统

#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;
}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值