编码过程:
- 1:将词典初始化为包含所有可能的单字符,当前前缀P初始化为空。
- 2:当前字符 C=字符流中的下一个字符。
3:判断 P+C 是否在词典中
(1) 如果“是”,则用C扩展P,即让P=P+C,返回步骤2
(2) 如果“否”,则:
输出与当前前缀P相对应的码字W;
将P+C添加到词典中;
令P=C,并返回步骤2
实际上就是从字典中匹配最长的串,输出其码字
然后该串加上下一个字符必定是不在字典中的,再将其加入字典即可
注意最后处理尾部
#include<iostream>
#include<string>
#include<map>
using namespace std;
int main(){
string s;
cin>>s;
int index = ;
map<string, int> m;
string ts;
for(int i=; i<; i++){
char c[] = {i, '\0'};
m[c] = i;
}
string p;
string c;
for(int i=; i<s.size(); i++){
c = s[i];
ts = p+c;
if(m.find(ts) != m.end()){
//在词典中: 更新前缀
p = ts;
}else{
//不在词典中: 添加至字典,并输出前缀词典值
int w = m[p];
cout<<w<<" ";
m.insert(pair<string, int>(ts, index++));
p = c;
}
}
//尾处理
int w = m[p];
cout<<w<<" ";
cout<<endl<<endl;
//打印字典
map<string, int>::iterator it = m.begin();
for(; it != m.end(); it++){
if(it->second > )
cout<<it->first<<"\t"<<it->second<<endl;
}
return ;
}
解码:
当 当前码字cw不在词典中时,唯一可能的情况是:下一个需要添加到词典中的串 就是cw所代表的串
#include<iostream>
#include<string>
#include<map>
using namespace std;
int main(){
int index = ;
map<int, string> m;
string ts;
for(int i=; i<; i++){
char c[] = {i, '\0'};
m[i] = string(c);
}
int i=;
string p;
string c;
int pw = -; //前一码字
int cw = -; //当前码字
cin>>pw;
cout<<m[pw];
while(cin>>cw){
if(m.find(cw) != m.end()){
//cw在词典中,直接输出
p = m[cw];
}else{
//cw不在词典中
p = m[pw];
p = p+c;
}
cout<<p;
c = p.substr(, );
m[index++] = m[pw]+c;
pw = cw;
i++;
//if(i == 5) break;
}
cout<<endl;
//打印字典
map<int, string>::iterator it = m.begin();
for(; it != m.end(); it++){
if(it->first > )
cout<<it->first<<"\t"<<it->second<<endl;
}
return ;
}