KAaha 发表于 2020-11-1 18:32:27

哈夫曼编码的代码 求大神解答 怎么才能正确运行

#include<iostream>
using namespace std;

typedef struct{
        int weight;
        int parent,lchild,rchild;
}HTNode,*HuffmanTree;

int min(HUffmanTree HT,int m)
{
        int i=0;
        int min;
        int min_weight;
        while(HT.parent!=0)
                i++;
        min_weight=HT.weight;
        min=i;
        for(i=1;i<m;i++)
        {
                if(HT.weight<min_weight && HT.parent==0)
                {
                        min_weight=HT.weight;
                        min=i;
                }
        }
        HT.parent=1;
        return min;
}
void Select(HuffmanTree HT,int m,int &s1,int &s2)
{
        int min1,min2;
        min1=min(HT,m);
        min2=min(HT,m);
}

void CreatHuffmanTree(HuffmanTree &HT,int n)
{
        if(n<=1) return;
        int m = 2*n-1;
        HT = new HTNode;
        int s1,s2;
        for(int i=1;i<=m;i++)
        {
                HT.parent=0;
                HT.lchild=0;
                HT.rchild=0;
        }
        for(int j=1;j<=n;++j)
                cin>>HT.weight;
        for(int k=n+1;k<=m;k++)
        {
                Select(HT,k-1,s1,s2);
                HT.parent=k;
                HT.parent=k;
                HT.lchild=s1;
                HT.rchild=s2;
                HT.weight=HT.weight+HT.weight;
        }
}
typedef char **HuffmanCode;
void CreatHuffmanCode(Huffman HT,HuffmanCode &HC,int n)
{
        HC=new char*;
        cd=new char;
        cd='\0';
        for(i=1;i<=n;i++)
        {
                start=n-1;
                c=i;f=HT.parent;
                while(f!=0)
                {
                        --start;
                        if(HT.lchild==c)
                                cd='0';
                        else
                                cd='1';
                        c=f;
                        f=HT.parent;
                }
                HC=new char;
                strcpy(HC,&cd);
        }
        delete cd;
}
int main()
{
        int n;


        cout<<"请输入结点个数:"<<endl;
        cin>>n;
        HTNode *HuffmanTree=new HTNode;
        int *weight=new int;
        char **HC=new char*;

        cout<<"请输入"<<n<<"个权值:";
        CreatHuffmanTree(HuffmanTree,n);
        CreatHuffmanCode(Huffman HT,Hsuffmancode HC,n);
        cout<<"输出哈夫曼编码:"<<endl;
        return 0;
}
       

昨非 发表于 2020-11-1 19:05:40

没有看你的错误,提供个完整的仅供参考
#include<iostream>
#include<string>
#include<limits.h>
using namespace std;

struct HNode                  //树结点(静态三叉链表)
{
        char name;   //结点内容
        int weight;//结点权重
        int parent;//双亲数组下标
        int LChild;//左孩子数组下标
        int RChild;//右孩子数组下标
};

struct HCode             //编码表中的每个元素
{
        char data;   //字符内容
        string code;//对应编码
};

static int a = { 0 };//权值数组
static char name = ""; //字符内容
static int n = 0;         //字符种类数

class Huffman
{
private:
        HNode* HTree = NULL;                   //哈夫曼树
        HCode* HCodeTable = NULL;            //存储编码表
        int N=0;                           //叶子数量
        void code(int i, string newcode);    //递归函数,对第i个结点编码
public:
       
        void CreateHTree(int a[], int n, char *name);//创建哈夫曼树
        void CreateCodeTable();                        //创建编码表
        void Encode(char* d,string &s);               //编码
        void Decode(char* s,char *d);               //解码
        void PrintHCodeTable();                     //打印编码表
        void PrintHTree();                            //打印哈夫曼树
        void printHfmTree(int root, int height, ostream& out);//直观打印
        void Analyze(string s,char *d);               //分析压缩效果
        ~Huffman();                                 //析构
};

//a[]为每种字符的权值,n为字符种类,name[]为各个字符的内容
void Huffman::CreateHTree(int a[], int n, char *name)
{
        N = n;                        //叶子数
        HCodeTable = new HCode;
        HTree = new HNode;   //初始化树的每个结点
        for (int i = 0; i < N; i++)
        {
                HTree.name = name;
                HTree.weight = a;
                HTree.LChild = HTree.RChild = HTree.parent = -1;
                HCodeTable.data = name;
        }

        int x=0, y=0;                  //开始建哈夫曼树
        for (int i = n; i < 2 * N - 1; i++)          //N个叶子,2*N-1个结点
        {
                int min1 = INT_MAX;//最小值,INT_MAX在<limits.h>中定义的
                int min2 = INT_MAX;//次小值
                for(int j = 0; j < i;j++)
                {
                        if (HTree.parent == -1)
                        {
                                if (HTree.weight < min1)
                                {
                                        min2 = min1;
                                        min1 = HTree.weight;
                                        y = x;
                                        x = j;
                                }
                                else if ((HTree.weight >= min1) && (HTree.weight < min2))
                                {
                                        min2 = HTree.weight;
                                        y = j;
                                }
                                else { ; }
                        }
                }
                HTree.parent = HTree.parent = i;   //父结点下标(实际意义:三结点相连)
                HTree.weight = HTree.weight + HTree.weight;
                HTree.LChild = x;
                HTree.RChild = y;
                HTree.parent = -1;    //待定,默认-1
        }
}

//递归函数,对第i个结点编码
void Huffman::code(int i, string newcode)   
{
        if (HTree.LChild == -1)//左子树空
        {
                HCodeTable.code = newcode;
                return;
        }
        code(HTree.LChild, newcode + "0");
        code(HTree.RChild, newcode + "1");
}

//生成编码表
void Huffman::CreateCodeTable()
{
        code(2 * N - 2, "");
}

//打印编码表
void Huffman::PrintHCodeTable()
{
        cout << "\t\t\t\t所建字符编码表如下:" << endl;
        cout << "\t\t\t\t--------------------------" << endl;
        cout << "\t\t\t\t字符内容\t" << "对应编码\t" << endl;
        for (int i = 0; i < N; i++)
        {
                cout <<"\t\t\t\t"<< HCodeTable.data << "\t\t" << HCodeTable.code << endl;
        }
        cout << "\t\t\t\t--------------------------" << endl;
}

//析构
Huffman::~Huffman()
{
        delete[]HTree;
        delete[]HCodeTable;
}

static string coded_string = "";   //用于存储对象字符串的编码串
static char text_out[] = "";       //存储解码结果

//编码 d为字符串,s为编码后的编码串
void Huffman::Encode(char* d,string &s)      
{
        int k = 0;
        while (d != '\0')
        {
                for (int i = 0; i < N; i++)
                {
                        if (HCodeTable.data == d)
                        {
                                s = s + HCodeTable.code;
                                break;
                        }
                }
                k++;
        }
        cout << "\t\t\t\t编码结果如下: "<< endl;
        cout <<"\t\t\t\t"<< s << endl;
}

// 解码 s为编码串,d为解码后的字符串
void Huffman::Decode(char* s,char* d)
{
        while (*s != '\0')
        {
                int parent = 2 * N - 2;      //根节点在HTree中的下标(共2*N-1个结点)
                while (HTree.LChild != -1)//有左孩子,不是叶子结点
                {
                        if (*s == '0')
                                parent = HTree.LChild;//左拐
                        else
                                parent = HTree.RChild;//右拐
                        s++;//后移一位
                }//目的:找下标parent
                *d = HCodeTable.data;
                d++;
        }
}

//打印Huffman树
void Huffman::PrintHTree()
{
        cout << "\t\t\t\t所建哈夫曼静态链表示如下:" << endl;
        cout << "\t\t\t\t==============================================" << endl;
        cout << "\t\t\t\t位置\t"<<"内容\t"<<"权值\t"<< "双亲\t" << "左孩子\t" << "右孩子\t" << endl;
        for (int i = 0; i < N * 2 - 1; i++)
        {
                cout <<"\t\t\t\t"<<i<<"\t"<<HTree.name<<"\t"<< HTree.weight << "\t" << HTree.parent << "\t"<< HTree.LChild << "\t" << HTree.RChild<< endl;
        }
        cout << "\t\t\t\t==============================================" << endl;
        //可视化直观打印
        cout << "\t\t\t\t该哈夫曼树打印如下(横向打印):" << endl << endl;
        printHfmTree(2 * N - 2, 0, cout);

}

//递归实现直观打印
void Huffman::printHfmTree(int root, int height, ostream& out)
{
        char branches[] = { " /\\<" };    //树枝图形
        if (root != -1)   
        {
                //先打印当前结点的右子树,并且深度+1
                printHfmTree(HTree.RChild, height + 1, out);//递归

                for (int i = 0; i < height; i++) out << "\t";//根据深度,右移

                out << HTree.weight;//输出权值

                //叶结点,则再打印出相应的字符
                if (HTree.LChild == -1 && HTree.RChild == -1)
                        out << "(" << HTree.name << ")";

                //打印树枝
                out << branches[((HTree.LChild != -1) << 1) | (HTree.RChild != -1)];

                //换行,打印当前结点的左子树
                out << endl;
                printHfmTree(HTree.LChild, height + 1, out);//递归
        }
}

//s为编码串,d为原字符串
void Huffman::Analyze(string s, char* d)         
{
        char* s1 = (char*)s.data();
        double m = 0, n = 0;
        while (*s1 != '\0') { m++; s1++; }
        while (*d != '\0') { n++; d++; }
        cout << "\t\t\t\t压缩比为:" << 100 * (m / 8.0) / n << "%" <<"\n"<< endl;
}

//测试函数
int main()            
{
        Huffman huffman1;//建树(默认构造)
        cout << "请输入需要操作的字符串:" << endl;
        char text;
        cin.getline(text, 128, '\n');
        text = '\0';

        int str_length = sizeof(text) / sizeof(text);
        char Character_range[] = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890 !\"#$%&\'()*+,-./:;<=>?@[\]^_`{|}~";
        //给定范围,支持所有可显示字符
        for (int i = 0; i < str_length; i++)   //遍历text
        {
                bool p = 0;   //标记
                for (int j = 0; j < n; j++)
                {
                        if (text == name)
                        {
                                a++; p = 1;
                                break;
                        }
                }
                for (int j = 0; j < strlen(Character_range)+1 && p == 0; j++)
                {
                        if (text == Character_range)
                        {
                                name = text;
                                a++; n++;
                                break;
                        }
                }
        }
        int length = 0;   //记录长度
        for (int i = 0; i < 128; i++)
        {
                length += a;
        }

        char* coded_str = (char*)coded_string.data();//类型转换,为参数准备
        cout << "\t\t\t\t\t 给定字符串统计结束,系统就绪!\n" << endl;

                cout << "\t\t\t\t       Welcome to the Huffman codingsystem!       \n";
                cout << "\t\t\t\t***************************************************\n";
                cout << "\t\t\t\t *    │1.打印Huffman树       2.打印编码表   │    *\n";
                cout << "\t\t\t\t *    │                                       │    *\n";
                cout << "\t\t\t\t *    │3.编码并打印          4.解码并打印   │    *\n";
                cout << "\t\t\t\t *    │                                       │    *\n";
                cout << "\t\t\t\t *    │5.计算压缩率          6.退出程序       │    *\n";
                cout << "\t\t\t\t***************************************************\n";
                cout << endl;

                huffman1.CreateHTree(a, n, name);//建树
                huffman1.CreateCodeTable();      //建表
       
                int select;
                do                                 
                {
                        cout << "\t\t\t\t请选择操作方式 (1~6):" << endl;
                        cin >> select;
                        if (select > 6)
                                cout << "错误操作,请重新输入!" << endl;
                        else
                        switch (select) {

                        case 1:
                                huffman1.PrintHTree();
                                break;

                        case 2:
                                huffman1.PrintHCodeTable();
                                break;

                        case 3:
                                huffman1.Encode(text,coded_string);
                                break;

                        case 4:                       
                                coded_str = (char*)coded_string.data();//类型转换
                                huffman1.Decode(coded_str, text_out);
                                text_out = '\0';
                                cout << "\t\t\t\t解码后的字符串为:" << "\n"<<text_out << "\n"<<endl;
                                break;

                        case 5:                                                
                                huffman1.Analyze(coded_string, text);
                                break;

                        case 6:
                                cout << "\t\t\t\t\tThank you for using!" << endl;
                        }
                } while (select != 6);
}

KAaha 发表于 2020-11-2 18:50:07

昨非 发表于 2020-11-1 19:05
没有看你的错误,提供个完整的仅供参考

我运行了这个也有错误

昨非 发表于 2020-11-2 19:05:59

KAaha 发表于 2020-11-2 18:50
我运行了这个也有错误

发报错

KAaha 发表于 2020-11-2 20:31:03

昨非 发表于 2020-11-2 19:05
发报错

D:\vc6.0\vc6.0 (2)\ka.cpp(28) : error C2252: 'HTree' : pure specifier can only be specified for functions
D:\vc6.0\vc6.0 (2)\ka.cpp(29) : error C2252: 'HCodeTable' : pure specifier can only be specified for functions
D:\vc6.0\vc6.0 (2)\ka.cpp(30) : error C2252: 'N' : pure specifier can only be specified for functions
D:\vc6.0\vc6.0 (2)\ka.cpp(48) : error C2065: 'N' : undeclared identifier
D:\vc6.0\vc6.0 (2)\ka.cpp(49) : error C2065: 'HCodeTable' : undeclared identifier
D:\vc6.0\vc6.0 (2)\ka.cpp(49) : error C2440: '=' : cannot convert from 'struct HCode *' to 'int'
      This conversion requires a reinterpret_cast, a C-style cast or function-style cast
D:\vc6.0\vc6.0 (2)\ka.cpp(50) : error C2065: 'HTree' : undeclared identifier
D:\vc6.0\vc6.0 (2)\ka.cpp(50) : error C2440: '=' : cannot convert from 'struct HNode *' to 'int'
      This conversion requires a reinterpret_cast, a C-style cast or function-style cast
D:\vc6.0\vc6.0 (2)\ka.cpp(53) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(53) : error C2228: left of '.name' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(54) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(54) : error C2228: left of '.weight' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(55) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(55) : error C2228: left of '.LChild' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(55) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(55) : error C2228: left of '.RChild' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(55) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(55) : error C2228: left of '.parent' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(56) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(56) : error C2228: left of '.data' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(60) : error C2374: 'i' : redefinition; multiple initialization
      D:\vc6.0\vc6.0 (2)\ka.cpp(51) : see declaration of 'i'
D:\vc6.0\vc6.0 (2)\ka.cpp(66) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(66) : error C2228: left of '.parent' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(68) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(68) : error C2228: left of '.weight' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(71) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(71) : error C2228: left of '.weight' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(75) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(75) : error C2228: left of '.weight' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(75) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(75) : error C2228: left of '.weight' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(77) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(77) : error C2228: left of '.weight' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(83) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(83) : error C2228: left of '.parent' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(83) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(83) : error C2228: left of '.parent' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(84) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(84) : error C2228: left of '.weight' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(84) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(84) : error C2228: left of '.weight' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(84) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(84) : error C2228: left of '.weight' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(85) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(85) : error C2228: left of '.LChild' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(86) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(86) : error C2228: left of '.RChild' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(87) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(87) : error C2228: left of '.parent' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(94) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(94) : error C2228: left of '.LChild' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(96) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(96) : error C2228: left of '.code' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(99) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(99) : error C2228: left of '.LChild' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(100) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(100) : error C2228: left of '.RChild' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(117) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(117) : error C2228: left of '.data' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(117) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(117) : error C2228: left of '.code' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(125) : error C2541: delete : cannot delete objects that are not pointers
D:\vc6.0\vc6.0 (2)\ka.cpp(126) : error C2541: delete : cannot delete objects that are not pointers
D:\vc6.0\vc6.0 (2)\ka.cpp(140) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(140) : error C2228: left of '.data' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(142) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(142) : error C2228: left of '.code' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(158) : error C2109: subscript requires array or pointer type
D:\vc6.0\vc6.0 (2)\ka.cpp(158) : error C2228: left of '.LChild' must have class/struct/union type
D:\vc6.0\vc6.0 (2)\ka.cpp(158) : fatal error C1903: unable to recover from previous error(s); stopping compilation
执行 cl.exe 时出错.

昨非 发表于 2020-11-2 20:39:46

啊这,我这里运行没问题啊,你用的啥编译器??

KAaha 发表于 2020-11-2 20:54:00

昨非 发表于 2020-11-2 20:39
啊这,我这里运行没问题啊,你用的啥编译器??

visual c++

Tlescept 发表于 2021-6-28 19:47:51

昨非 发表于 2020-11-1 19:05
没有看你的错误,提供个完整的仅供参考

需要加头文件<string.h>
页: [1]
查看完整版本: 哈夫曼编码的代码 求大神解答 怎么才能正确运行