给定一个字符串,进行哈夫曼编码
#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,至少比用指针写起来看着舒服点^_^