数据结构课程设计

#include<iostream>
#include<iomanip>
#include<Windows.h>
#include"good.h"
#include <string.h>
#include <stdlib.h> 
using namespace std;
typedef struct{
	char data;
	int weight;
	int parent, lchild, rchild;
}HTNode, *HuffmanTree;
typedef char * * HuffmanCode;
void Select(HuffmanTree &HT, int n, int m)
{
	HuffmanTree p = HT;
	int tmp;
	for (int j = n + 1; j <= m; j++)
	{
		int tag1, tag2, s1, s2;
		tag1 = tag2 = 32767;
		for (int x = 1; x <= j - 1; x++)
		{
			if (p[x].parent == 0 && p[x].weight<tag1)
			{
				tag1 = p[x].weight; s1 = x;
			}
		}
		for (int y = 1; y <= j - 1; y++)
		{
			if (p[y].parent == 0 && y != s1&&p[y].weight<tag2)
			{
				tag2 = p[y].weight; s2 = y;
			}
		}
		if (s1>s2)  //将选出的两个节点中的序号较小的始终赋给s1
		{
			tmp = s1; s1 = s2; s2 = tmp;
		}
		p[s1].parent = j;
		p[s2].parent = j;
		p[j].lchild = s1;
		p[j].rchild = s2;
		p[j].weight = p[s1].weight + p[s2].weight;
	}
}
void HuffmanCoding(HuffmanTree &HT, int n, char *w1, int*w2)
{
	int m = 2 * n - 1;
	if (n <= 1)   return;
	HT = (HuffmanTree)malloc((m + 1)*sizeof(HTNode));
	HuffmanTree p = HT;
	for (int i = 1; i <= n; i++)
	{
		p[i].data = w1[i - 1];
		p[i].weight = w2[i];
		p[i].parent = p[i].lchild = p[i].rchild = 0;
	}
	for (int i=1; i <= m; i++)
	{
		p[i].weight = p[i].parent = p[i].lchild = p[i].rchild = 0;
	}
	Select(HT, n, m);
	ofstream outfile;        //生成hfmTree文件
	outfile.open("hfmTree.txt", ios::out);
	for (int i = 1; i <= m; i++)
	{
		outfile << HT[i].weight << "\t" << HT[i].parent << "\t" << HT[i].lchild
			<< "\t" << HT[i].rchild << "\t" << endl;
	}
	outfile.close();
	cout << "初始化结果已保存在hfmTree文件中\n";
}
void ToBeTree()            //将正文写入文件ToBeTree中
{
	ofstream outfile;
	outfile.open("ToBeTree.txt", ios::out);
	outfile << "THIS PROGRAM IS MYFAVORITE";
	outfile.close();
}
void Encoding(HuffmanTree &HT, int n)    //编码
{
	HuffmanCode HC;
	HC = (HuffmanCode)malloc((n + 1)*sizeof(char *));
	char *cd;
	cd = (char *)malloc(n*sizeof(char));
	cd[n - 1] = '\0';
	for (int k = 1; k <= n; k++)
	{
		int start = n - 1;
		for (int c = k, f = HT[k].parent; f != 0; c = f, f = HT[f].parent)
		{
			if (HT[f].lchild == c) cd[--start] = '0';
			else cd[--start] = '1';
		}
		HC[k] = (char *)malloc((n - start)*sizeof(char));
//		strcpy(HC[k], &cd[start]);
	}
	cout << "输出哈夫曼编码:" << endl;
	for (int h = 1; h <= n; h++)           //输出编码
	{
		cout << HT[h].data << ":";
		cout << HC[h];
		cout << "  ";
		if (h % 8 == 0)  cout << endl;
	}
	cout << endl << "输出正文编码:" << endl;
	ToBeTree();
	//读取TOBETREE文件里的正文,并进行编码
	fstream infile;
	infile.open("ToBeTree.txt", ios::in);
	char s[80];
	while (!infile.eof())
	{
		infile.getline(s, sizeof(s));
	}
	infile.close();
	fstream outfile;
	outfile.open("CodeFile.txt", ios::out);
	int count = 0;
	for (int h = 0; s[h] != '\0'; h++)
	{
		for (int k = 1; k <= n; k++)
		if (s[h] == HT[k].data)
		{
			cout << HC[k];
			cout << " ";
			count++;
			outfile << HC[k];
			break;
		}
		if (count % 9 == 0)  cout << endl;     //每输出7个换行
	}
	outfile.close();
	cout << "\n编码结果已保存在文件CodeFile中.";
	cout << endl;
}
void Decoding(HuffmanTree &HT, int n)   //译码
{
	int f = 2 * n - 1;
	fstream infile;
	infile.open("CodeFile.txt", ios::in);
	char s[1000];
	while (!infile.eof())
	{
		infile.getline(s, sizeof(s));
	}
	infile.close();
	int i = 0;
	int j = 0;
	fstream outfile;
	outfile.open("TextFile.txt", ios::out);
	while (s[i] != '\0')
	{
		f = 2 * n - 1;
		while (HT[f].lchild != 0)//以f对应的节点的左孩子的值==0作为结束
		{
			if (s[j] == '0')   f = HT[f].lchild;
			else          f = HT[f].rchild;
			j++;
		}
		i = j;
		cout << HT[f].data;
		outfile << HT[f].data;
	}
	outfile.close();
	cout << "\n译码结果已保存在文件TextFile中.";
	cout << endl;
}
void Print()          //印代码文件
{
	int count = 0;
	fstream infile;
	infile.open("CodeFile.txt", ios::in);
	char s[1000];
	while (!infile.eof())
	{
		infile.getline(s, sizeof(s));
		for (int i = 0; s[i] != '\0'; i++)
		{
			cout << s[i];
			count++;
			if (count % 50 == 0)  cout << endl; //在终端上每行显示50个代码
		}
	}
	infile.close();
	cout << endl;
}
char menu()              //菜单函数
{
	cout << "功能菜单如下:" << endl;
	cout << "* * * * * * * * * * * * * * * * * * * * *" << endl;
	cout << "       1:初始化(Initialization)       " << endl;
	cout << "       2:编码(Encoding)           " << endl;
	cout << "       3:译码(Decoding)           " << endl;
	cout << "       4:印代码文件(Print)         " << endl;
	cout << "       5:退出(Exit)               " << endl;
	cout << "* * * * * * * * * * * * * * * * * * * * *" << endl;
	cout << "请输入功能字符:";
	char ch;
	cin >> ch;
	return ch;
}
void voidmain()
{
	int n;
	int Array[100];
	char cArray[100];
	HuffmanTree HT;
	cout << "输入n个字符:";
	cin >> cArray;
	n = strlen(cArray);
	cout << "一共" << n << "个字符.\n";
	cout << "依次输入各个字符的权值:" << endl;
	for (int i = 1; i <= n; i++)     cin >> Array[i];
	int tag;
	char x = menu();
	while (1)
	{
		
		switch (x)
		{
		case '1':HuffmanCoding(HT, n, cArray, Array); break;
		case '2':Encoding(HT, n); break;
		case '3':Decoding(HT, n); break;
		case '4':Print(); break;
		case '5':tag = 0; cout << "结束" << endl; break;
		default:cout << "你输入错误!" << endl;
		}
		if (tag == 0) break;
		cout << "y(继续) or n(退出)" << endl;
		char ch;
		cin >> ch;
		if (ch == 'y')
		{
			cout << "请输入功能字符:";
			char c;
			cin >> c;
			x = c;
		}
		
	}
}

void shuchu1(jiami&c)
{
	for (int i = 0; i < c.length; i++)
		c.shuchu[i] = c.shuru[i];
	for (int i = 0; i < c.length; i++)
		cout << setw(3) << c.shuchu[i];
}
void displaya1()
{
	cout << "**********************************" << endl;
	cout << "               主菜单             " << endl;
	cout << "----------------------------------" << endl;
	cout << "|1.选择要加密的算法或者是改变字符|" << endl;
	cout << "|    2.输出已经加密过的字符      |" << endl;
	cout << "|    3. 输入要加密的字符         |" << endl;
	cout << "|    4.       解密               |" << endl;
	cout << "|    5.保存已经加密的字符        |" << endl;
	cout << "|    6.读取已经保存的字符        |" << endl;
	cout << "|    7. 退出菜单                 |" << endl;
	cout << "|    8.哈夫曼编程:              |" << endl;
	cout << "----------------------------------" << endl;
	cout << "**********************************" << endl;
}
void displayb1()
{
	cout << "----------------------------------" << endl;
	cout << "|    1.        加密算法1         |" << endl;
	cout << "|    2.        加密算法2         |" << endl;
	cout << "|    3.   是否要插入字符?       |" << endl;
	cout << "|    4.       删除字符           |" << endl;
	cout << "|    5.          返回            |" << endl;
	cout << "----------------------------------" << endl;
}

void exit()
{
	cout << "欢迎使用!" << endl;
	system("exit");
}
void main()
{
	
	char n;
	jiami chen;
	manhui:
	displaya1();
	cout << "请输入你的选项!" << endl;
	cin >> n;
	while (n<49||n>58)  //判断所输入的选项是否在1~5之间,若在则跳过循环执行下面的语句,否则就重新输入,直到输入正确
	{
		cout << "你的输入有误,请重新输入" << endl;
			cin >> n;
	}
	switch (n)
	{
	case '1':
		system("cls");
		if (chen.length==0)
		{
			cout << "你还没输入要加密的字符,不能进行加密,请先输入字符" << endl;
			cout << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << endl;
			cout << "系统自动返回界面!" << endl;
			goto manhui;
		}
		hui:
		displayb1();
		char k;
		cout << "请输入你要执行的序号" << endl;
		cin >> k;
		while (k<49 || k>53)  //判断所输入的选项是否在1~4之间,若在则跳过循环执行下面的语句,否则就重新输入,直到输入正确
		{
			cout << "你的输入有误,请重新输入" << endl;
			cin >> k;
		}
		switch (k)
		{
		case '1':
			system("cls");
			chen.suanfa_a();
			goto manhui;
		case '2':
			chen.suanfa_b();
			goto manhui;
			break;
		case '3':
			system("cls");
			cout << "请分别输入你要插入的位置和字符是:" << endl;
			int a; char u;
			cin >>a>> u;
			chen.Insert(a,u);
			cout << "插入成功!" << endl;
			goto hui;
		case '4':
			system("cls");
			cout << "请输入你要删除字符的位置是:" << endl;
			int h;
			cin >> h;
			chen.Delete(h);
			cout << "删除成功!" << endl;
			goto hui;
		case '5':
			goto manhui;
			break;

		}

		goto manhui;
		break;
	case '2':
		if (chen.length == 0||!chen.panduan)
		{
			system("cls");
			cout << "你还没输入要加密的字符,不能进行输出,请先输入字符:" << endl;
			cout << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << endl;
			cout << "系统自动返回界面!" << endl;
			goto manhui;
		}
		cout << "加密后的算法是:" << endl;
		shuchu1(chen);
		cout << "请问是否还要继续?若是请按y,不是就按n" << endl;
		char f;
		cin >> f;
		if (f == 121)
			goto manhui;
		if (f == 110);
		system("exit");
		break;
	case '3':
		system("cls");
		cout << "请输入你要加密的字符,当输入!字符时停止输入" << endl;
		chen.shuru1();
		goto manhui;
	case '4':
		system("cls");
		if (chen.length == 0)
		{
			cout << "你还没输入要加密的字符,不能进行输出,请先输入字符!!" << endl;
			cout << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << endl;
			cout << "系统自动返回界面!" << endl;
			goto manhui;
		}
		chen.jiemi();
		goto manhui;
	case'5':
		if (chen.length == 0||!chen.panduan)
		{
			system("cls");
			cout << "你还没输入要加密的字符,不能进行保存,请先输入字符!" << endl;
			cout << "或者你还没有进行加密!" << endl;
			cout << "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << endl;
			cout << "系统自动返回界面!" << endl;
			goto manhui;
		}
		chen.savech();
		cout << "保存成功!" << endl;
		goto manhui;
	case'6':
		system("cls");
		chen.readch();
		cout << "读取已经保存的字符成功!" << endl;
		goto manhui;
	case '7':
		exit();
		break;
	case '8':
		voidmain();
		goto manhui;


	}
	system("pause");
	

}
#include<iomanip>
#include<iomanip>
#include"good.h"
#include<fstream>
using namespace std;
jiami::jiami()
{
	shuru[0] = '1';
}
void jiami::shuru1()
{
	for (length; length < maxsize; length++)
	{
		cin >> shuru[length];
		if (shuru[length] == 33)
		{
			cout << "你已输入了!字符,所以输入停止,并返回主菜单" << endl;
			break;
		}
		if (length >= 1000)
			cout << "你的输入字符的长度已经超过了有效的长度!" << endl;
	}
	cout << "返回选择界面" << endl;
	
}
void jiami::exit()
{
}
int jiami::length_a()
{
	int h;
	h = strlen(shuru);
	return h;
}
void jiami::savech()
{
	ofstream SaveFile("manhui.txt");   //打开文件
	for (int i = 0; i < length;i++)
	SaveFile << shuru[i];
	SaveFile.close();
}
int jiami::copych()
		{
			char ch;
			ifstream sfile("D:\\manhui.txt");               //以输入方式打开文件
			ofstream tfile("E:\\chen.txt");                     //以输出的方式打开文件
			if (!sfile)
			{
				cout << "不能打开源文件:" << "D:\\manhui.txt" << endl;
				return -1;
			}
			if (!tfile)
			{
				cout << "不能打开目标文件:" << "E:\\chen.txt" << endl;
				return -1;
			}
			sfile.unsetf(ios::skipws);                  //把跳过空格控制位置0
			while (sfile >> ch)                 //依次从文件读取字符存入ch
				tfile << ch;          //将ch输出到目标文件
			sfile.close();
			tfile.close();
			return 0;
		}
void jiami::readch()

{
	ifstream readfile("manhui.txt", ios::in | ios::binary);
	readfile >> shuru;
	cout << shuru;
	readfile.close();
}
void jiami::Insert(int i,char p)
{
	if (length >= maxsize) throw"上溢";
	if (i<1 || i>length + 1)throw"位置非法!";
	for (int j = length; j >= i; j--)
		shuru[j] = shuru[j - 1];
	shuru[i - 1] = p;
	length++;

}
int jiami::Delete(int i)
{
	if (length == 0)throw"下溢!";
	if (i<1 || i>length)throw"位置非法!";
	char y = shuru[i - 1];
	for (int j = i; j < length; j++)
		shuru[j - 1] = shuru[j];
	length--;
	return y;
}
#include<iostream>
#include<iomanip>
#include<windows.h>
#include<fstream>
#include <fstream>
#include <string.h>
#include <stdlib.h>  
using namespace std;
const int maxsize = 1000;                //定义要最长加密字符的最大长度为1000
class jiami
{
public:
	jiami();            //将要存储的字符数组设置为1
	void shuru1();
	friend void shuchu1(jiami&c);
	void suanfa_a()                           //设定ASCII码值平移的位移量为3
	{
		for (int i = 0; i < length; i++)
			shuru[i] = (shuru[i] + 3) % 255;
		panduan = true;
		cout << "已经对输入的字符进行了加密算法1" << endl;
	}
	void suanfa_b()
	{
		for (int i = 0; i < length; i++)
						shuru[i] = (shuru[i] + 5)%255;
					panduan = true;
		cout << "已经对输入的字符进行了加密算法2" << endl;
			
	}
	void jiemi()
	{
		char a, b, c;
		a = 'a', b = 'b', c = 'c';
		cout << "请输入你之前哪种加密的,按1.为进行了加密1,按2.为进行了加密2!!" << endl;
		char o;
		cin >> o;
		while (o!=49&&o!=50)  //判断所输入的选项是否在1和2之间,若在则跳过循环执行下面的语句,否则就重新输入,直到输入正确
		{
			cout << "你的输入有误,请重新输入" << endl;
			cin >> o;
		}
		if (o = 49)
		{
			cout << "解密的字符是:" << endl;
			for (int i = 0; i < length; i++)
			{
				shuru[i] = (shuru[i] - 3) % 255;
				cout << setw(4) << shuru[i];
			}
		}
		if (o=50)
		for (int i = 0; i < length; i++)
		{
				shuru[i] = (shuru[i] -5)%255;
					cout << setw(4) << shuru[i];

		}
		cout << "已经对字符进行解密" << endl;

	}
	void exit();
	int length_a();
	int copych();                   //复制文件
	void savech();                  //保存字符
	int length = 0;            //定义字符长度
	bool panduan = false;
	void readch();  //读取已经保存的字符
	void Insert(int i,char p);        //插入字符
	int Delete(int i);          //删除字符
private:
	char shuru[maxsize], shuchu[maxsize];
};

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值