ReZero's Utopia.

哈夫曼编码

Word count: 1kReading time: 5 min
2016/10/30 Share

给定一个字符串,进行哈夫曼编码

#include <bits/stdc++.h>

using namespace std;

typedef struct node{
    int num;
    string data;
    node(int _num, string _data){
        num = _num; data = _data;
    }
}node;

bool operator<(const node &a, const node &b){
     return a.num > b.num;
}


int main(){
    int kase = 1;
    string line;
    while(getline(cin, line)){
        int chr[30] = {0};
        string answer[30];
        priority_queue<node> que;
        int len = line.length();
        for(int i = 0; i < len; ++i){
            chr[line[i] - 'A']++;
        }
        for(int i = 0; i < 26; ++i){
            if(chr[i]){
                string p = "";
                que.push(node(chr[i], p + char('A' + i)));
            }
        }

        int n = que.size() - 1;
        if(n > 0){
            for(int i = 0; i < n; ++i){
                node a = que.top(); que.pop();
                node b = que.top(); que.pop();
                for(int j = 0; j < a.data.size(); ++j){
                    answer[a.data[j]-'A'] += '0';
                }
                for(int j = 0; j < b.data.size(); ++j){
                    answer[b.data[j]-'A'] += '1';
                }
                que.push(node(a.num + b.num, a.data + b.data));
            }
            cout << "Case #" << kase++ << ":" << endl;
            for(int i = 0; i < 26; ++i){
                if(chr[i]){
                    reverse(answer[i].begin(), answer[i].end());
                }
            }
            ///对answer字符串数组排序:相同chr的字符串按字典序排
            for(int i = 0; i < 26; ++i){
                for(int j = i; j < 26; ++j){
                    if(chr[i] == chr[j]){
                        if(answer[j] < answer[i]){
                            swap(answer[i], answer[j]);
                        }
                    }

                }
            }
            ///以上对answer字符串数组排序:相同chr的字符串按按字典序排
            for(int i = 0; i < 26; ++i){
                if(chr[i]){
                    printf("%c: %s\n", i + 'A',answer[i].c_str());
                }
            }
            int sum = 0;
            for(int i = 0; i < 26; ++i){
                sum += answer[i].size() * chr[i];
            }
            cout << sum;
            if(sum < 50){
                cout << " ";
                for(int i = 0; i < len; ++i){
                    cout << answer[line[i] - 'A'];
                }
            }
        } else if (n == 0){
            node fina = que.top();
            cout << fina.data << ":" << 0 << endl;
            cout << len;
            if(len < 50){
                cout << " ";
                for(int i = 0; i < len; ++i){
                    cout << 0;
                }
            }
        }
        cout << endl;

    }

}

开心的wrong answer 正在查,
已查出错误,字典序保证方式出错 要保证为字典序不能后期排
因为要考虑同时保证最子权与父权的构建关系
不能生成后才排序编码

而应是最简最直接思路
- 排好序后进行编码

#include <bits/stdc++.h>

using namespace std;

typedef struct node{
    int num;
    string data;
    node(int _num, string _data){
        num = _num; data = _data;
    }
    bool operator<(const node &b)const{
         ///重点唯一改动
         if (num == b.num) return data[0] > b.data[0];
         return num > b.num;
    }
}node;



int main(){
    int kase = 1;
    string line;
    while(getline(cin, line)){
        int chr[30] = {0};
        string answer[30];
        priority_queue<node> que;
        int len = line.length();
        for(int i = 0; i < len; ++i){
            chr[line[i] - 'A']++;
        }
        for(int i = 0; i < 26; ++i){
            if(chr[i]){
                string p = "";
                que.push(node(chr[i], p + char('A' + i)));
            }
        }
        int n = que.size() - 1;
        if(n > 0){
            for(int i = 0; i < n; ++i){
                node a = que.top(); que.pop();
                node b = que.top(); que.pop();
                for(int j = 0; j < a.data.size(); ++j){
                    answer[a.data[j]-'A'] += '0';
                }
                for(int j = 0; j < b.data.size(); ++j){
                    answer[b.data[j]-'A'] += '1';
                }
                que.push(node(a.num + b.num, a.data + b.data));
            }
            cout << "Case #" << kase++ << ":" << endl;
            for(int i = 0; i < 26; ++i){
                if(chr[i]){
                    reverse(answer[i].begin(), answer[i].end());
                }
            }
            ///对answer字符串数组排序:相同chr的字符串按字典序排
            for(int i = 0; i < 25; ++i){
                for(int j = 0; j < 25 - i; ++j){
                    if(chr[j] && chr[j+1])
                    if(chr[j] == chr[j+1]){
                        if(answer[j] > answer[j+1]){
                            swap(answer[j+1], answer[j]);
                        }
                    }

                }
            }
            ///以上对answer字符串数组排序:相同chr的字符串按按字典序排
            for(int i = 0; i < 26; ++i){
                if(chr[i]){
                    printf("%c: %s\n", i + 'A',answer[i].c_str());
                }
            }
            int sum = 0;
            for(int i = 0; i < 26; ++i){
                sum += answer[i].size() * chr[i];
            }
            cout << sum;
            if(sum < 50){
                cout << " ";
                for(int i = 0; i < len; ++i){
                    cout << answer[line[i] - 'A'];
                }
            }
        } else if (n == 0){
            node fina = que.top();
            cout << "Case #" << kase++ << ":" << endl;
            cout << fina.data << ": " << 0 << endl;
            cout << len;
            if(len < 50){
                cout << " ";
                for(int i = 0; i < len; ++i){
                    cout << 0;
                }
            }
        }
        cout << endl;

    }

}

这里写图片描述

勉强A的挺6,至少比用指针写起来看着舒服点^_^

CATALOG