哈夫曼编码
#include <iostream>
#include <cstring>
#include <set>
#include<time.h>
#include<Windows.h>
using namespace std;
#define maxn 20000
#define STR_LEN 10
#define CHAR_MIN 'a'
#define CHAR_MAX 'z'
int n;
char s[1000005];
char a[1000005];
typedef struct node
{
int weight;
int parent, lchild, rchild;
}HufNode;
typedef struct code
{
int weight;
char data;
char code[maxn];
}Hufcode;
Hufcode h1[maxn];
HufNode h[maxn];
void creat();
void begin();
void Init(Hufcode* h1);
void select(HufNode* h, int k, int& s1, int& s2);
void HuffmanTree(Hufcode* h1, HufNode* h);
void EnCodeing(Hufcode* h1);
int search(Hufcode* h1, char* s);
void DeCodeing(Hufcode* h1);
int main()
{
clock_t start, finish;
double part1,part2;
do {
FILE* fp = fopen("log.txt", "a");
creat();
begin();
Init(h1);
HuffmanTree(h1, h);
start = clock();
EnCodeing(h1);
finish = clock();
part1 = (double)(finish - start) / CLOCKS_PER_SEC;
fprintf(fp, "|--->>>\tEnCodeing time=%.3lfsec", part1);
start=clock();
DeCodeing(h1);
finish = clock();
part2 = (double)(finish - start) / CLOCKS_PER_SEC;
fprintf(fp, "\n|--->>>\tDeCodeing time=%.3lfsec", part2);
time_t t;
struct tm* st;
t = time(NULL);
st = localtime(&t);
double times = (double)clock() / CLOCKS_PER_SEC;
fprintf(fp, "\n|--->>>\ttotaltime=%.3lfsec\t\t", times);
fprintf(fp, "%d-%d-%d %2d:%2d:%2d\n\n\n", st->tm_year + 1900, st->tm_mon + 1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec);
fclose(fp);
printf("\n是否继续:(输入0截止,输入其他字符继续)\n");
} while (getchar() != '0');
return 0;
}
int search(Hufcode* h1, char* s)
{
for (int i = 0; i < n; i++)
if (strcmp(h1[i].code, s) == 0)
return i;
return -1;
}
void creat()
{
FILE* creat = fopen("需加密的文本.txt", "w");
FILE* c2 = fopen("log.txt", "a");
char str[STR_LEN + 1] = { 0 };
int i;
int lenth;
srand(time(NULL));
do { lenth = rand() % STR_LEN; } while (lenth < 3);
for (i = 0; i < STR_LEN; i++)
{
if(STR_LEN<26)
str[i] = rand() % lenth + CHAR_MIN;
else
str[i] = rand() % (CHAR_MAX - CHAR_MIN + 1) + CHAR_MIN;
}
fprintf(creat,"%s\n", str);
if (STR_LEN < 26)
fprintf(c2, "random select: %d\n", lenth);
else
fprintf(c2, "random select: NULL\n");
fclose(creat);
fclose(c2);
}
void begin()
{
FILE* fp = fopen("需加密的文本.txt", "r");
FILE* f = fopen("log.txt", "a");
fprintf(f, "source file:");
memset(s, 0, sizeof(s));
int num[26] = { 0 };
set<int> sub;
while (fscanf(fp, "%s", s) != EOF)
{
fprintf(f, "%s", s);
for (int i = 0; s[i]; i++)
{
int t = s[i] - 'a';
if (t >= 0 && t <= 25)
{
num[t]++;
sub.insert(t);
}
}
cout << s << endl;
}
fprintf(f, "\n");
fclose(fp);
fclose(f);
FILE* f1 = fopen("建立哈夫曼树用.txt", "w");
FILE* f2 = fopen("log.txt", "a");
fprintf(f1, "%d", sub.size());
fprintf(f2, "char count:%d", sub.size());
for (int i = 0; i < 26; i++)
if (num[i])
{
fprintf(f1, " %d%c", num[i], 97 + i);
fprintf(f2, " %d%c", num[i], 97 + i);
}
fclose(f1);
fclose(f2);
}
void Init(Hufcode* h1)
{
FILE* fp = fopen("建立哈夫曼树用.txt", "r");
fscanf(fp, "%d", &n);
for (int i = 0; i < n; i++)
fscanf(fp, "%d%c", &h1[i].weight, &h1[i].data);
fclose(fp);
}
void select(HufNode* h, int k, int& s1, int& s2)
{
int i;
for (i = 0; i < k && h[i].parent != 0; i++);
s1 = i;
for (i = 0; i < k; i++)
if (h[i].parent == 0 && h[i].weight < h[s1].weight)
s1 = i;
for (i = 0; i < k; i++)
if (h[i].parent == 0 && i != s1)
{
s2 = i;
break;
}
for (i = 0; i < k; i++)
if (h[i].parent == 0 && i != s1 && h[i].weight < h[s2].weight)
s2 = i;
}
void HuffmanTree(Hufcode* h1, HufNode* h)
{
memset(s, 0, sizeof(s));
int m = 2 * n - 1;
for (int i = 0; i < m; i++)
{
if (i < n)
h[i].weight = h1[i].weight;
else
h[i].weight == 0;
h[i].lchild = h[i].parent = h[i].rchild = 0;
}
int s1, s2;
for (int i = n; i < m; i++)
{
select(h, i, s1, s2);
h[s1].parent = i;
h[s2].parent = i;
h[i].lchild = s1;
h[i].rchild = s2;
h[i].weight = h[s1].weight + h[s2].weight;
}
s[n] = '\0';
int l;
for (int i = 0; i < n; ++i)
{
l = n - 1;
for (int k = i, p = h[k].parent; p; k = p, p = h[k].parent) {
if (k == h[p].lchild)
s[l] = '0';
else
s[l] = '1';
l--;
}
strcpy(h1[i].code, s + l + 1);
cout << h1[i].data << " " << h1[i].code << endl;
}
FILE* f1 = fopen("字符编码.txt", "w");
FILE* f2 = fopen("log.txt", "a");
fprintf(f2, "\nhufftree:\n");
for (int i = 0; i < n; i++)
{
fprintf(f1, "%c %s\n", h1[i].data, h1[i].code);
fprintf(f2, "%c %s\n", h1[i].data, h1[i].code);
}
fclose(f1);
fclose(f2);
}
void EnCodeing(Hufcode* h1)
{
FILE* fp = fopen("需加密的文本.txt", "r");
FILE* f1 = fopen("加密后得到的电文.txt", "w");
FILE* f2 = fopen("log.txt", "a");
fprintf(f2, "encode result:");
memset(s, 0, sizeof(s));
while (fscanf(fp, "%s", s) != EOF)
{
for (int i = 0; s[i]; i++)
{
for (int j = 0; j < n; j++)
{
if (s[i] == h1[j].data)
{
fprintf(f1, "%s", h1[j].code);
fprintf(f2, "%s", h1[j].code);
cout << h1[j].code;
}
}
}
fprintf(f2, "\n");
}
cout << endl;
fclose(fp);
fclose(f1);
fclose(f2);
}
void DeCodeing(Hufcode* h1)
{
FILE* f1 = fopen("加密后得到的电文.txt", "r");
FILE* f2 = fopen("解密后得到的文本.txt", "w");
FILE* f3 = fopen("log.txt", "a");
memset(s, 0, sizeof(s));
while (fscanf(f1, "%s", s) != EOF)
{
fprintf(f3, "decode result:");
memset(a, 0, sizeof(a));
int len = strlen(s), k = 0;
for (int i = 0; i < len; i++)
{
a[k] = s[i];
a[k + 1] = '\0';
int t = search(h1, a);
if (t != -1)
{
fprintf(f2, "%c", h1[t].data);
fprintf(f3, "%c", h1[t].data);
cout << h1[t].data;
k = 0;
continue;
}
k++;
}
fprintf(f3, "\n");
}
fclose(f1);
fclose(f2);
fclose(f3);
}