#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];
};
数据结构课程设计
最新推荐文章于 2023-05-07 20:20:04 发布