C++哈夫曼树编码对文章进行压缩,请前辈帮我看看哪错了

罗宾范佩西 2017-10-29 01:20:19

#ifndef _HFTREE_
#define _HFTREE_

#include <string>
using namespace std;

template<class Type>
class hfTree {
private:
struct Node
{
Type data;
int weight;
int parent, left, right;
};
Node * elem;
int length;
public:
struct hfCode {
Type data;
string code;
};

hfTree(const Type *x, const int * w, int size);
void getCode(hfCode result[]);
~hfTree() { delete [] elem; }


};


template<class Type>
hfTree<Type>::hfTree(const Type * v, const int * w, int size)
{
const int max = 32767;
int min1, min2;//最小树,次最小树的权值
int x, y;//最小树,次最小树的下标

length = 2 * size;
elem = new Node[length];
//将数表初始化
for (int i = size; i < length; ++i)
{
elem[i].weight = w[i - size];
elem[i].data = v[i - size];
elem[i].parent = elem[i].left = elem[i].right = 0;
}
//归并森林中的树
for (int i = size - 1; i > 0; --i)
{
min1 = min2 = max; x = y = 0;
for (int j = i + 1; j<length; ++j)
if (elem[j].parent == 0)
if (elem[j].weight<min1)
{
min2 = min1; min1 = elem[j].weight; x = y; y = j;
}
else if (elem[j].weight<min2)
{
min2 = elem[j].weight; x = j;
}//第52-61:找出待归并的两棵树
elem[i].weight = min1 + min2;
elem[i].left = x; elem[i].right = y; elem[i].parent = 0;
elem[x].parent = i; elem[y].parent = i;
}
}



template<class Type>
void hfTree<Type>::getCode(hfCode result[])
{
int size = length / 2;
int p, s;//p是s的父节点
for (int i = size; i<length; ++i)
{
result[i - size].data = elem[i].data;
result[i - size].code = " ";
p = elem[i].parent; s = i;
while (p) {
if (elem[p].left == s)
result[i - size].code = "0" + result[i - size].code;
else result[i - size].code = "1" + result[i - size].code;
s = p; p = elem[p].parent;
}
}
}


#endif // !1

#include"hfTree.h"
#include<iostream>
#include <string>
using namespace std;
/*
输入一篇英文文章,统计每个字符出现的次数,
并以此构造哈夫曼树和输出每个字符的哈夫曼编码,
最后输出这篇文章的编码。
*/
int main()
{
struct Wen
{
char abc;
int weight;
}; Wen *elems;
//结点指针保存文章的字符和权重
cout << "请输入一段英文,按回车键结束。" << endl;
string str;
getline(cin, str);

int str_lenth = str.length();
elems=new Wen [str_lenth];
int _length = 0;

for (int j = 0; j < str_lenth; j++)
for (int i = 0; i <= j; i++)
{
if (elems[i].abc== str[j])
{
elems[i].weight++; break;
}
else if(elems[i].abc==0)
elems[i].abc = str[j];
elems[i].weight = 1;
_length++;
}//两次for循环统计文章相同的字符和权重
char *xx = new char[_length];
int *ww = new int[_length];
for (int i = 0; i < _length; i++) {
xx[i] = elems[i].abc;
ww[i] = elems[i].weight;
}//将文章出现的字符和权重保存在两个数组中

hfTree<char>tree(xx, ww, _length);
hfTree<char>::hfCode result [200];

tree.getCode(result);
for (int i = 0; i < _length; ++i)
cout << result[i].data << " " << result[i].code <<endl;
system("pause");
return 0;

}


头文件是引用书的,主函数是自己写的,希望前辈帮我看看哪里要改,编译时没有错误,无法运行
上次发的50分贴不见了,这下重新发,没有分了
...全文
287 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_45358005 2019-11-21
  • 打赏
  • 举报
回复
#include <iostream> #include <string> using namespace std; struct huffTree { int parent; int lchild; int rchild; int weight; string flag; }; struct Lowest_node { char ch; int ch_num; }; void coding(int length,huffTree *tree,int n,int &a,int &b) { int i; int r,s; r=s=length; for (i=0;i<n;i++) { if (tree[i].weight<r && tree[i].parent==-1) { r=tree[i].weight; a=i; } } for (i=0;i<n;i++) { if (tree[i].weight<s && i!=a && tree[i].parent==-1) { s=tree[i].weight; b=i; } } } void frequency(string str) { int i,j; int length=str.length(); Lowest_node *node=new Lowest_node[length]; for (i=0;i<length;i++) node[i].ch_num=0; int char_type_num=0; for (i=0;i<length;i++) { for (j=0;j<char_type_num;j++) if (str[i]==node[j].ch) break;// if (j<char_type_num) node[j].ch_num++; else { node[j].ch=str[i]; node[j].ch_num++; char_type_num++; } } for (i=0;i<char_type_num;i++) { for (j=i;j<char_type_num;j++) { if (node[j].ch_num<node[j+1].ch_num) { int temp; char ch_temp; temp=node[j].ch_num; ch_temp=node[j].ch; node[j].ch_num=node[j+1].ch_num; node[j].ch=node[j+1].ch; node[j+1].ch_num=temp; node[j+1].ch=ch_temp; } } } for (i=0;i<char_type_num;i++) cout<<"字符"<<node[i].ch<<"出现了"<<node[i].ch_num<<"次"<<endl; huffTree *huff=new huffTree[2*char_type_num-1]; huffTree temp; string *code=new string[2*char_type_num-1]; for (i=0;i<2*char_type_num-1;i++) { huff[i].lchild=-1; huff[i].parent=-1; huff[i].rchild=-1; huff[i].flag=-1; } for (j=0;j<char_type_num;j++) huff[j].weight=node[j].ch_num; int min1,min2; if(char_type_num==1) { cout<<"1"<<endl; } else { for (int k=char_type_num;k<2*char_type_num-1;k++) { coding(length,huff,k,min1,min2); huff[min1].parent=k; huff[min2].parent=k; huff[min1].flag="0"; huff[min2].flag="1"; huff[k].lchild=min1; huff[k].rchild=min2; huff[k].weight=huff[min1].weight+huff[min2].weight; } for (i=0;i<char_type_num;i++) { temp=huff[i]; while (1) { if (temp.parent==-1) break;// code[i]=temp.flag+code[i]; temp=huff[temp.parent]; } } int sum=0; for(i=0;i<char_type_num;i++) { sum+=(code[i].length()*node[i].ch_num); } cout<<sum<<endl; } cout<<"字符串的每个字符huffman编码为:"<<endl; for (i=0;i<char_type_num;i++) cout<<node[i].ch<<" "<<code[i]<<endl; cout<<"整个字符串的huffman编码为:"<<endl; for (i=0;i<length;i++) { //S? for (j=0;j<char_type_num;j++) { if (str[i]==node[j].ch) cout<<code[j]; } } delete[] node; node=NULL; delete[] huff; huff=NULL; delete[] code; code=NULL; } int main() { int length=0; string str; getline(cin,str); frequency(str); system("pause"); return 0; } //请输入一个字符串:2333abcde //字符3出现了3次 //字符2出现了1次 //字符a出现了1次 //字符b出现了1次 //字符c出现了1次 //字符d出现了1次 //字符e出现了1次 //字符串的每个字符huffman编码为: //3 11 //2 000 //a 001 //b 010 //c 011 //d 100 //e 101 //整个字符串的huffman编码为: //000111111001010011100101 我改成了识别所有char字符,包括空格啥的
罗宾范佩西 2017-10-29
  • 打赏
  • 举报
回复
引用 2 楼 zhao4zhong1 的回复:
仅供参考:
#include <iostream>
#include <string>
using namespace std;
struct huffTree {
    int parent;
    int lchild;
    int rchild;
    int weight;
    string flag;
};
struct Lowest_node {
    char ch;
    int ch_num;
};
void coding(int length,huffTree *tree,int n,int &a,int &b) {
    int i;
    int r,s;

    r=s=length;
    for (i=0;i<n;i++) {
        if (tree[i].weight<r
         && tree[i].parent==-1) {
            r=tree[i].weight;
            a=i;
        }
    }
    for (i=0;i<n;i++) {
        if (tree[i].weight<s
         && i!=a
         && tree[i].parent==-1) {
            s=tree[i].weight;
            b=i;
        }
    }
}
void frequency(string str) {
    int i,j;
    int length=str.length();
    Lowest_node *node=new Lowest_node[length];

    for (i=0;i<length;i++) node[i].ch_num=0;

    int char_type_num=0;
    for (i=0;i<length;i++) {
        for (j=0;j<char_type_num;j++)
            if (str[i]==node[j].ch
            || ('a'<=node[j].ch && node[j].ch<='z'
                && str[i]+32==node[j].ch))
                break;//
        if (j<char_type_num) node[j].ch_num++;
        else {
            if ('A'<=str[i] && str[i] <= 'Z') node[j].ch=str[i]+32;
            else node[j].ch=str[i];
            node[j].ch_num++;
            char_type_num++;
        }
    }
    for (i=0;i<char_type_num;i++) {
        for (j=i;j<char_type_num;j++) {
            if (node[j].ch_num<node[j+1].ch_num) {
                int temp;
                char ch_temp;
                temp=node[j].ch_num;
                ch_temp=node[j].ch;
                node[j].ch_num=node[j+1].ch_num;
                node[j].ch=node[j+1].ch;
                node[j+1].ch_num=temp;
                node[j+1].ch=ch_temp;
            }
        }
    }
    for (i=0;i<char_type_num;i++)
        cout<<"字符"<<node[i].ch<<"出现了"<<node[i].ch_num<<"次"<<endl;
    huffTree *huff=new huffTree[2*char_type_num-1];
    huffTree temp;
    string *code=new string[2*char_type_num-1];

    for (i=0;i<2*char_type_num-1;i++) {
        huff[i].lchild=-1;
        huff[i].parent=-1;
        huff[i].rchild=-1;
        huff[i].flag=-1;
    }
    for (j=0;j<char_type_num;j++) huff[j].weight=node[j].ch_num;
    int min1,min2;
    for (int k=char_type_num;k<2*char_type_num-1;k++) {
        coding(length,huff,k,min1,min2);
        huff[min1].parent=k;
        huff[min2].parent=k;
        huff[min1].flag="0";
        huff[min2].flag="1";
        huff[k].lchild=min1;
        huff[k].rchild=min2;
        huff[k].weight=huff[min1].weight+huff[min2].weight;
    }
    for (i=0;i<char_type_num;i++) {
        temp=huff[i];
        while (1) {
            code[i]=temp.flag+code[i];
            temp=huff[temp.parent];
            if (temp.parent==-1) break;//
        }
    }
    cout<<"字符串的每个字符huffman编码为:"<<endl;
    for (i=0;i<char_type_num;i++) cout<<node[i].ch<<"  "<<code[i]<<endl;
    cout<<"整个字符串的huffman编码为:"<<endl;
    for (i=0;i<length;i++) {                                                                                     //S?
        for (j=0;j<char_type_num;j++) {
            if (str[i]==node[j].ch)
                cout<<code[j];
        }
    }
    delete[] node;
    node=NULL;
    delete[] huff;
    huff=NULL;
    delete[] code;
    code=NULL;
}
int main() {
    int length=0;
    string str;
    cout<<"请输入一个字符串:";
    cin>>str;
    frequency(str);
    return 0;
}
//请输入一个字符串:2333abcde
//字符3出现了3次
//字符2出现了1次
//字符a出现了1次
//字符b出现了1次
//字符c出现了1次
//字符d出现了1次
//字符e出现了1次
//字符串的每个字符huffman编码为:
//3  11
//2  000
//a  001
//b  010
//c  011
//d  100
//e  101
//整个字符串的huffman编码为:
//000111111001010011100101
可以看看我写的代码主函数部分是哪错了吗,编译没有提示。
赵4老师 2017-10-29
  • 打赏
  • 举报
回复
仅供参考:
#include <iostream>
#include <string>
using namespace std;
struct huffTree {
    int parent;
    int lchild;
    int rchild;
    int weight;
    string flag;
};
struct Lowest_node {
    char ch;
    int ch_num;
};
void coding(int length,huffTree *tree,int n,int &a,int &b) {
    int i;
    int r,s;

    r=s=length;
    for (i=0;i<n;i++) {
        if (tree[i].weight<r
         && tree[i].parent==-1) {
            r=tree[i].weight;
            a=i;
        }
    }
    for (i=0;i<n;i++) {
        if (tree[i].weight<s
         && i!=a
         && tree[i].parent==-1) {
            s=tree[i].weight;
            b=i;
        }
    }
}
void frequency(string str) {
    int i,j;
    int length=str.length();
    Lowest_node *node=new Lowest_node[length];

    for (i=0;i<length;i++) node[i].ch_num=0;

    int char_type_num=0;
    for (i=0;i<length;i++) {
        for (j=0;j<char_type_num;j++)
            if (str[i]==node[j].ch
            || ('a'<=node[j].ch && node[j].ch<='z'
                && str[i]+32==node[j].ch))
                break;//
        if (j<char_type_num) node[j].ch_num++;
        else {
            if ('A'<=str[i] && str[i] <= 'Z') node[j].ch=str[i]+32;
            else node[j].ch=str[i];
            node[j].ch_num++;
            char_type_num++;
        }
    }
    for (i=0;i<char_type_num;i++) {
        for (j=i;j<char_type_num;j++) {
            if (node[j].ch_num<node[j+1].ch_num) {
                int temp;
                char ch_temp;
                temp=node[j].ch_num;
                ch_temp=node[j].ch;
                node[j].ch_num=node[j+1].ch_num;
                node[j].ch=node[j+1].ch;
                node[j+1].ch_num=temp;
                node[j+1].ch=ch_temp;
            }
        }
    }
    for (i=0;i<char_type_num;i++)
        cout<<"字符"<<node[i].ch<<"出现了"<<node[i].ch_num<<"次"<<endl;
    huffTree *huff=new huffTree[2*char_type_num-1];
    huffTree temp;
    string *code=new string[2*char_type_num-1];

    for (i=0;i<2*char_type_num-1;i++) {
        huff[i].lchild=-1;
        huff[i].parent=-1;
        huff[i].rchild=-1;
        huff[i].flag=-1;
    }
    for (j=0;j<char_type_num;j++) huff[j].weight=node[j].ch_num;
    int min1,min2;
    for (int k=char_type_num;k<2*char_type_num-1;k++) {
        coding(length,huff,k,min1,min2);
        huff[min1].parent=k;
        huff[min2].parent=k;
        huff[min1].flag="0";
        huff[min2].flag="1";
        huff[k].lchild=min1;
        huff[k].rchild=min2;
        huff[k].weight=huff[min1].weight+huff[min2].weight;
    }
    for (i=0;i<char_type_num;i++) {
        temp=huff[i];
        while (1) {
            code[i]=temp.flag+code[i];
            temp=huff[temp.parent];
            if (temp.parent==-1) break;//
        }
    }
    cout<<"字符串的每个字符huffman编码为:"<<endl;
    for (i=0;i<char_type_num;i++) cout<<node[i].ch<<"  "<<code[i]<<endl;
    cout<<"整个字符串的huffman编码为:"<<endl;
    for (i=0;i<length;i++) {                                                                                     //S?
        for (j=0;j<char_type_num;j++) {
            if (str[i]==node[j].ch)
                cout<<code[j];
        }
    }
    delete[] node;
    node=NULL;
    delete[] huff;
    huff=NULL;
    delete[] code;
    code=NULL;
}
int main() {
    int length=0;
    string str;
    cout<<"请输入一个字符串:";
    cin>>str;
    frequency(str);
    return 0;
}
//请输入一个字符串:2333abcde
//字符3出现了3次
//字符2出现了1次
//字符a出现了1次
//字符b出现了1次
//字符c出现了1次
//字符d出现了1次
//字符e出现了1次
//字符串的每个字符huffman编码为:
//3  11
//2  000
//a  001
//b  010
//c  011
//d  100
//e  101
//整个字符串的huffman编码为:
//000111111001010011100101
罗宾范佩西 2017-10-29
  • 打赏
  • 举报
回复
怎么回事,这一贴在首页也找不到

15,440

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧