#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
set<int>st;
int Fre[10000];
typedef struct
{
int weight;
int parent, lchild, rchild;
}HTnode,*Huffmantree;
typedef char **Huffmancode;
void select(Huffmantree T, int p, int &s1, int &s2)
{
int mini = inf;
for (int i = 1; i <= p; i++)
{
if (st.count(i))continue;
if (mini > T[i].weight)
{
mini = T[i].weight;
s1 = i;
}
}
st.insert(s1);
mini = inf;
for (int i = 1; i <= p; i++)
{
if (st.count(i)) continue;
if (mini > T[i].weight)
{
mini = T[i].weight;
s2 = i;
}
}
st.insert(s2);
}
void CreatTree(Huffmantree &T, int n)
{
if (n <= 1)
return;
int m = 2 * n - 1;
T = new HTnode[m + 1];
for (int i = 1; i <= m; i++)
{
T[i].parent = 0;
T[i].lchild = T[i].rchild = 0;
}
for (int i = 1; i <= n; i++)
T[i].weight = Fre[i];
for (int i = n + 1; i <= m; i++)
{
int s1, s2;
select(T, i - 1, s1, s2);
T[s1].parent = i; T[s2].parent = i;
T[i].lchild = T[s1].weight > T[s2].weight ? s2 : s1;
T[i].rchild=T[s1].weight > T[s2].weight ? s1 : s2;
T[i].weight = T[s1].weight + T[s2].weight;
}
}
void CreatHuffmancode(Huffmantree T, Huffmancode &HC, int n)
{
HC = new char *[n + 1];
char *cd = new char[n];
cd[n - 1] = '\0';
for (int i = 1; i <= n; i++)
{
int start = n - 1;
int c = i;
int f = T[i].parent;
while (f != 0)
{
--start;
if (T[f].lchild == c)
cd[start] = '0';
else
cd[start] = '1';
c = f; f = T[f].parent;
}
HC[i] = new char[n - start];
strcpy(HC[i], &cd[start]);
}
delete cd;
}
int CreatFre(string s)
{
set<int>fre;
int cnt = 0;
for (int i = 0; i < s.size(); i++)
{
if (isalpha(s[i]))
{
s[i] = tolower(s[i]);
Fre[s[i] - 'a'+1]++;
if (fre.count(s[i] - 'a')==0)
{
fre.insert(s[i] - 'a');
cnt++;
}
}
}
return cnt;
}
void TravelTree(Huffmancode HC, int n)
{
for (int i = 1; i <= n; i++)
{
printf("%c->", i + 96);
for (int j = 0; HC[i][j] != '\0'; j++)
printf("%c", HC[i][j]);
puts("");
}
}
/*void replace(string s,Huffmancode HC,ofstream outFile)
{
}*/
int main()
{
ios::sync_with_stdio(false);
ifstream inFile;
ofstream outFile;
outFile.open("outData.txt");
inFile.open("SourceFile.txt");
string s;
printf("please input a string :");
inFile>>s;
int len=CreatFre(s);
Huffmantree T;
// len++;
CreatTree(T, len);
Huffmancode HC;
CreatHuffmancode(T, HC, len);
TravelTree(HC, len);
for (int i = 0; i < s.size(); i++)
{
if (isalpha(s[i]))
{
s[i] = tolower(s[i]);
int t = s[i] - 'a' + 1;
for (int j = 0; HC[t][j]; j++)
outFile<<HC[t][j];
}
}
inFile.close();
outFile.close();
system("pause");
return 0;
}