香农:
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <bitset>
#include <math.h>
#include <ctype.h>
#include <time.h>
#include <queue>
#include <map>
#include <set>
using namespace std;
const int MAXN = 11000;
double p[MAXN], sump[MAXN], li[MAXN];
int n, LI[MAXN];
char code[MAXN][100];
bool cmp(double a, double b)
{
return a > b;
}
void init()
{
cout << "请依次输入信源符号的概率:";
memset(p, 0, sizeof(p));
memset(sump, 0, sizeof(sump));
for (int i = 1; i <= n; i++)
cin >> p[i];
sort(p + 1, p + 1 + n, cmp);
for (int i = 2; i <= n; i++)
sump[i] = sump[i - 1] + p[i - 1];
}
void solve()
{
for (int i = 1; i <= n; i++)
{
li[i] = (-1)*(log10(p[i]) / log10(2));
LI[i] = ceil(li[i]);
}
for (int i = 1; i <= n; i++)
{
for (int j = 0; j < LI[i]; j++)
{
sump[i] *= 2;
if (sump[i] - 1 >= 0)
{
code[i][j] = '1';
sump[i] -= 1;
}
else
code[i][j] = '0';
}
}
cout << "编码为:" << endl;
for (int i = 1; i <= n; i++)
cout << code[i] << " ";
cout << endl;
}
int main()
{
cout << "请输入信源符号个数n:";
cin >> n;
{
init();
solve();
}
return 0;
}
/*
测试数据:
7
0.20 0.19 0.18 0.17 015 0.10 0.01
*/
费诺:
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <bitset>
#include <math.h>
#include <ctype.h>
#include <time.h>
#include <queue>
#include <map>
#include <set>
#include <iomanip>
using namespace std;
int n;
double p[10000];
string *code;
void fano(int a, int b)
{
if ((b - a) >= 1)
{
double sum = 0;
for (int i = a; i <= b; i++)
sum += p[i];
double s1 = 0, *s = new double[10];
for (int i = a; i <= b; i++)
{
s1 += p[i]; s[i] = fabs(2 * s1 - sum) / sum;
}
double min = s[a]; int c;
for (int i = a; i <= b; i++)
if (s[i] <= min)
{
min = s[i]; c = i;
}
for (int i = a; i <= b; i++)
{
if (i <= c) code[i] += "0";
else code[i] += "1";
}
if (c == a)
fano(c + 1, b);
else if (c == b - 1)
fano(a, c);
else
{
fano(a, c); fano(c + 1, b);
}
}
}
void init()
{
cout << "请输入信源符号个数n:";
cin >> n;
code = new string[n];
cout << "请依次输入信源符号的概率:";
for (int i = 0; i<n; i++) cin >> p[i];
for (int i = 0; i<n - 1; i++)
for (int j = i + 1; j<n; j++)
if (p[i] < p[j])
{
double temp = p[i]; p[i] = p[j]; p[j] = temp;
}
}
void solve()
{
fano(0, n - 1);
cout << endl << endl << setw(8) << "概率" << setw(8) << "码字" << endl;
for (int i = 0; i<n; i++)
cout << setw(8) << p[i] << setw(8) << code[i] << setw(8) << endl;
delete[]code;
}
int main()
{
init();
solve();
return 0;
}
/*
测试数据:
6
0.32 0.22 0.18 0.16 0.08 0.04
8
0.25 0.25 0.125 0.125 0.0625 0.0625 0.0625 0.0625
*/
尾随后缀:
//代码:
#include <stdio.h>
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <algorithm>
#include <vector>
#include <string.h>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <sstream>
#include <time.h>
using namespace std;
int n, ok, num;
char s[100000][100], tmp[100];
char F[100000][100];
set<string> Ftmp;
void input()
{
puts("请输入码字的个数:");
cin >> n;
puts("请输入码字:");
for (int i = 1; i <= n; i++)
scanf("%s", s[i]);
}
void Sort()
{
for (int i = 1; i <= n; i++)
{
for (int j = i; j <= n; j++)
{
int len1 = strlen(s[i]);
int len2 = strlen(s[j]);
if (len1 > len2)
{
strcpy(tmp, s[i]);
strcpy(s[i], s[j]);
strcpy(s[j], tmp);
}
}
}
}
bool isok(char a[], char b[])
{
int len1 = strlen(a);
int len2 = strlen(b);
for (int i = 0; i < len1; i++)
{
if (a[i] != b[i])
return false;
}
return true;
}
void init()
{
Ftmp.clear();
ok = 0;
num = 0;
for (int i = 1; i < n; i++)
{
for (int j = i + 1; j <= n; j++)
{
int len1 = strlen(s[i]);
int len2 = strlen(s[j]);
if (isok(s[i], s[j]))
{
strcpy(tmp, s[j] + len1);
strcpy(F[num++], tmp);
}
}
}
for (int i = 0; i < num; i++)
Ftmp.insert(F[i]);
}
void solve()
{
int pos = 0;
for (int i = 0; i < num; i++)
{
for (int j = 1; j <= n; j++)
{
int len1 = strlen(F[i]);
int len2 = strlen(s[j]);
if (len1 < len2)
{
if (isok(F[i], s[j]))
{
strcpy(tmp, s[j] + len1);
strcpy(F[num++], tmp);
int size = Ftmp.size();
Ftmp.insert(tmp);
if (Ftmp.size() == size)
num -= 1;
}
}
}
}
}
void test()
{
puts("检验结果:");
int ok = 0;
for (int i = 0; i < num; i++)
{
if (ok) break;
for (int j = 1; j <= n; j++)
{
if (!strcmp(F[i], s[j]))
{
puts("非唯一可译码");
ok = 1;
break;
}
}
}
if (!ok) puts("是唯一可译码");
printf("\n");
puts("尾随后缀集合是:");
for (int i = 0; i < num; i++)
Ftmp.insert(F[i]);
set<string> ::iterator it;
for (it = Ftmp.begin(); it != Ftmp.end(); it++)
cout << *it << " "; cout << endl;
}
int main()
{
input();
Sort();
init();
solve();
test();
return 0;
}
//测试数据
/*
6
0 10 1100 1110 1011 1101
5
110 11 100 00 10
*/
















