編碼過程:
- 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 = 256;
map<string, int> m;
string ts;
for(int i=0; i<256; i++){
char c[2] = {i, '\0'};
m[c] = i;
}
string p;
string c;
for(int i=0; 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 > 255)
cout<<it->first<<"\t"<<it->second<<endl;
}
return 0;
}
解碼:
當 當前碼字cw不在詞典中時,唯一可能的情況是:下一個需要添加到詞典中的串 就是cw所代表的串
#include<iostream>
#include<string>
#include<map>
using namespace std;
int main(){
int index = 256;
map<int, string> m;
string ts;
for(int i=0; i<256; i++){
char c[2] = {i, '\0'};
m[i] = string(c);
}
int i=1;
string p;
string c;
int pw = -1; //前一碼字
int cw = -1; //當前碼字
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(0, 1);
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 > 255)
cout<<it->first<<"\t"<<it->second<<endl;
}
return 0;
}