LZW編碼解碼cpp實現

編碼過程:

  • 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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章