信息论上学习了fano编码,所以就尝试着自己写一遍fano编码
#include "iostream"
#include <fstream>
#include "map"
#include "string"
#include "math.h"
using namespace std;
multimap<float, pair<string, string>> W;
void show(multimap<float, pair<string, string>> word);
typedef decltype(W.begin()) map_pointer;
int initial(string file_name, int max){
float probability = 0, temp = 0;
string str = "";
ifstream infile;
infile.open(file_name, ios::in);
for (int i = 0; i < max; ++i){
infile >> temp >> str;
probability += temp;
W.insert({ temp, make_pair(str, "") });
}
if ((probability - 1) < 0.0001){
return 1;
}else{
cout << "Sum of probability != 1" << endl;
return 0;
}
}
int make_code(map_pointer high_pointer, map_pointer low_pointer){
float high_value = high_pointer->first, low_value = low_pointer->first;
auto hp = high_pointer, lp = low_pointer;
hp->second.second += "1";
lp->second.second += "0";
while (1){
if (++hp == lp){//can not hp + 1
--hp;
if (hp != high_pointer){
make_code(high_pointer, hp);
}
if (lp != low_pointer){
make_code(lp, low_pointer);
}
return 1;
}else if (high_value >= low_value){
--hp;
--lp;
low_value += lp->first;
lp->second.second += "0";
}else{
--hp;
++hp;
high_value += hp->first;
hp->second.second += "1";
}
}
}
void show(multimap<float, pair<string, string>> word){
ofstream Outfile;
Outfile.open("text.txt", ios::out);
Outfile << "***********************************************************" << endl;
for (auto &m : word){
Outfile << m.second.first << "\t" << m.second.second << endl;
cout << m.second.first << "\t" << m.second.second << endl;
}
}
int main(){
initial("probability_68.txt", 68);
if (make_code(W.begin(), --W.end())){
show(W);
}else{
cout << "error" << endl;
}
system("pause");
}
最后上传一个68个字符概率的文件(空格用下划线_代替)
0.02 _
0.012 ,
0.009 .
0.0037 ?
0.0009 ;
0.0031 !
0.00029 A
0.0014 B
0.00072 C
0.0009 D
0.0006 E
0.00071 F
0.0037 G
0.00051 H
0.00032 I
0.001 J
0.00081 K
0.00022 L
0.00021 M
0.00023 N
0.00024 O
0.00002 P
0.00038 Q
0.0002 R
0.0005 S
0.0007 T
0.00027 U
0.00003 V
0.0008 W
0.0017 X
0.0003 Y
0.0019 Z
0.064 a
0.013 b
0.0061 c
0.0246 d
0.0663 e
0.0111 f
0.0913 g
0.0555 h
0.09 i
0.02173 j
0.002 k
0.0064 l
0.0084 m
0.1254 n
0.07 o
0.0068 p
0.0059 q
0.0083 r
0.0219 s
0.0172 t
0.0936 u
0.00001 v
0.017 w
0.009 x
0.054 y
0.03 z
0.00131 0
0.00131 1
0.00131 2
0.00131 3
0.00131 4
0.00131 5
0.00131 6
0.00131 7
0.00131 8
0.00131 9