鱼非愚而为瑜 2023-05-03 14:40 采纳率: 50%
浏览 6
已结题

赫夫曼编码问题:疑似指针指向报错

问题:
多次修改程序,但总是出现分配出错问题,不知道怎么改善。
看了好几天,不知道怎么改。

错误截图:

img

代码功能是:
在一个txt文件里读取所有字符,统计出现的次数,并用赫夫曼编码显示。

代码:

头文件:


#ifndef HEADER_H_
#define HEADER_H_

//赫夫曼树
typedef struct
{
    char ch;
    int weight;
    int parent, lchlld, rchild;
}HTNode,*HuffmanTree;

//赫夫曼编码表
typedef char** HuffmanCode;

typedef struct SqList
{
    char ch;
    int weight;
}SqList,*Sq;

//读取文件
int File_to_SQ(const char* filename, Sq& sql);

void HuffmanCoding(HuffmanTree& HT, HuffmanCode& HC, const Sq&SQ, int n);

void Weight_Select(const HuffmanTree& HT, int n, int& s1, int& s2);
#endif

方式实现源文件:

#include"header.h"
#include<iostream>
#include<stdlib.h>


void Weight_Select(const HuffmanTree& HT, int i, int& s1, int& s2)
{
    s1 = s2 = 0;
    for (int n = 1; n <= i; n++)
    {
        if (HT[n].parent == 0)
        {
            //两个 if 条件语句,只能执行一个,使得优先让s1成为最小值,
            //让s2继承s1之前的值。
            if (s1 == 0 || HT[n].weight < HT[s1].weight)
            {
                s2 = s1;
                s1 = n;
            }
            else if (s2 == 0 || HT[n].weight < HT[s2].weight)
            {
                s2 = n;
            }
        }
    }
}

void HuffmanCoding(HuffmanTree& HT, HuffmanCode& HC, const Sq&SQ, int n)
{
    if (n <= 1)
        return;
    //赫夫曼树总结点数
    int m;
    m = 2 * n - 1;
    int i;
    HuffmanTree p;//移动指针
    Sq ps;//创建移动指针
    for (p = HT + 1, i = 0,ps=SQ+1; i < n; ++i, ++p, ++ps)
    {
        *p = { ps->ch,ps->weight,0,0,0 };
        //charArr[i] = ps->ch;
    }
    //i=n
    for (; i <= m; ++i, ++p)
    {
        //储存字符  权重  父节点  左子树  右子树
        *p = { '\0',0,0,0,0 };
    }

    //最小值  第二最小值
    int s1, s2;

    //走到这步n至少等于2,m=2n-1
    for (i = n + 1; i <= m; ++i)
    {
        //从HT+1到HT+i-1中寻找到parent==0的两个最小值下标
        Weight_Select(HT, i - 1, s1, s2);
        
        //两个最小值和i连接成夫结点与左右子树
        HT[s1].parent = i; HT[s2].parent = i;
        HT[i].lchlld = s1; HT[i].rchild = s2;
        HT[i].weight = HT[s1].weight + HT[s2].weight;
    }

    //生成赫夫曼编码
    // HC = new char*[n];
    //赫夫曼编码缓存
    char* code = new char[n];
    code[n-1] = '\0';

    //HT[1] ~HT[n]
    for (i = 1; i <=n; ++i)
    {
        int start = n - 1;
        int c = i;
        int p = HT[i].parent;
        //从叶子结点向上直到根来得出赫夫曼编码
        //叶子结点的父节点为根
        while (p != 0)
        {
            if (HT[p].lchlld == c)
                code[--start] = '0';
            else
                code[--start] = '1';
            c = p;
            p = HT[p].parent;
        }
        //为每个字符分配赫夫曼编码的储存空间
        HC[i - 1] = new char[n- start];
        //复制到对应赫夫曼编码表中
        strcpy_s(HC[i - 1], n - start, &code[start]);
    }
    delete[] code;
    code = NULL;
}

#include<fstream>
int File_to_SQ(const char* filename, Sq& sql)
{
    using namespace std;
    ifstream InFile;
    InFile.open(filename);
    if (!InFile.is_open())
    {
        exit(EXIT_FAILURE);
    }
    char ch;
    int count=0;
    while (InFile >> ch)
    {
        count = 1;
        while (sql[count].ch!='\0' && ch != sql[count].ch)
            count++;
        if (sql[count].ch=='\0')
        {
            sql[count].ch = ch;
            sql[count].weight = 1;
        }
        else
        {
            sql[count].weight++;
        }
    }
    InFile.close();
    return count;
}

main文件:

#include<iostream>
#include"header.h"

#define MAXSIZE 30
int main()
{
    using namespace std;
    
    //
    Sq SqL = new SqList[MAXSIZE]();
    int num=File_to_SQ("school-profile.txt", SqL);
    int i;
    //
    //cout << "number:\n";
    //int num;
    //cin >> num;
    ////创建新数组
    //Sq SqL=new SqList[num+1];
    //Sq sqf;
    //int i;
    //cout << "character & weight:\n";
    //for (i = 0,sqf=SqL+1; i < num; ++i,++sqf)
    //{
    //    cout << "character: ";
    //    cin >> sqf->ch;
    //    cout << "weigth: ";
    //    cin >> sqf->weight;
    //}
    //
    HuffmanTree HT=new HTNode[2*num]; 
    HT[0]={0,0,0,0,0};
    HuffmanCode HC=new char *[num];
    HuffmanCoding(HT, HC, SqL, num);
    for (i = 1; i <= 2 * num - 1; i++)
    {
        cout << HT[i].ch << "\t";
        cout << HT[i].weight << "\t";
        cout << HT[i].parent << '\t';
        cout << HT[i].lchlld << '\t';
        cout << HT[i].rchild << endl;
    }
    cout << "character\tweight\tcode\n";
    for (i = 0; i < num; ++i)
    {
        cout << "\t" << HT[i + 1].ch;;
        cout << "\t" << HT[i + 1].weight;
        cout << "\t" << HC[i] << endl;
    }

    //销毁指针
    for (i = 0; i < num; i++)
    {
        delete HC[i];
    }
    delete[] SqL;
    delete[] HC;
    delete[] HT;
    
    return 0;
}

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-05-03 16:05
    关注
    • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/7693560
    • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:实现一个小程序,把txt文件里面的十六进制数据读取出来,转成bin文件
    • 除此之外, 这篇博客: 编程实现.txt文本中空格的统计(包括每行文本空格的统计)中的 程序代码如下: 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
    • 下面展示一些 内联代码片

      #include <stdio.h>
      #include <string.h>
      //#include <>
      int main()
      {      
         char szTest[1000] = {0};//定义承接字符用来存放每行数据 
         //int len = 0;  
         //int sl;
         int count=0;  //统计每行的空格次数,并将其输出。 
         int sum=0;    //用于统计所有的空格数 
         int hs=0;     //行数的统计 
         FILE *fp = fopen("C:/Users/user/Desktop/1.txt", "r");    
         if(fp == NULL) //检测相关路径中是否有相应的文档    
         {          
             printf("failed to open dos.txt\n"); //if没有相应的文档时的报错信息        
             return 1;         
         }
         while(!feof(fp))  //检测是否读完  
         {          
             memset(szTest,0, sizeof(szTest));                 
             fgets(szTest,sizeof(szTest) - 1, fp); // 包含了换行符 
      	   printf("\n"); 
      	   printf("%s\n",szTest);  //输出每行内容 
      	   printf("该字符串长度为:%d\n",strlen(szTest));
      	   //sl=strlen(szTest);
             for(int i=0;i<=strlen(szTest);i++){  //遍历每行字符检查 
         	        if(szTest[i]==' '){  //是否有空格‘ ’ 
      	             count++;  
      	        } 			
         	   }
        	   printf("第%d行的空格数为:%d",hs+1,count); 
        	   sum+=count;
      	   count=0;
      	   hs++; 
      	   printf("\n");  
             //printf("%s",szTest);      
         }
         printf("\n");
         printf("\n所查文档中所有的空格数为:%d\n",sum); 
         fclose(fp);  
         printf("\n");        
         return 0;
      }
      
      

      相关代码的注解在旁边大家可以很快的理解一下,因为本人在编写过程中,有一部分代码是用来调试程序的运行的,所以在上面都注释掉啦!可能会影响代码的美观性,希望大家谅解!

      本人文件:
      在这里插入图片描述
      路径:
      在这里插入图片描述
      内容:
      在这里插入图片描述

      在这里插入图片描述
      在这里插入图片描述
      大家可以仔细地理解一下代码哦!此代码比较简单的!

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 5月6日
  • 创建了问题 5月3日

悬赏问题

  • ¥15 poi合并多个word成一个新word,原word中横版没了.
  • ¥15 【火车头采集器】搜狐娱乐这种列表页网址,怎么采集?
  • ¥15 求MCSCANX 帮助
  • ¥15 机器学习训练相关模型
  • ¥15 Todesk 远程写代码 anaconda jupyter python3
  • ¥15 我的R语言提示去除连锁不平衡时clump_data报错,图片以下所示,卡了好几天了,苦恼不知道如何解决,有人帮我看看怎么解决吗?
  • ¥15 在获取boss直聘的聊天的时候只能获取到前40条聊天数据
  • ¥20 关于URL获取的参数,无法执行二选一查询
  • ¥15 液位控制,当液位超过高限时常开触点59闭合,直到液位低于低限时,断开
  • ¥15 marlin编译错误,如何解决?