c++-Huffman树的问题,输入要统计的文件就闪掉

问题描述

Huffman树的问题,输入要统计的文件就闪掉
#include "stdafx.h"
#include<iostream>
#include<fstream>
#include<cstring>
#include<iomanip>
using namespace std;

typedef struct huffmannode
{
    char ch;
    int weight;
    int parent;
    int lchild;
    int rchild;
    int index;             //记录编码在数组中出现的位置
    char code[40];//记录每一个字符的编码
}*huffmannodetree;

typedef struct countfreqnode
{
    char nm;
    int freq;
    countfreqnode* next;

}*countfrelist;

//统计文件中,每个字符出现的频率
countfrelist & counthelp(char *filename){
        countfrelist L;
        countfreqnode *pt;
        char a;
        ifstream infile;
        L = new countfreqnode;  //统计数据存入链表中,头结点
        L->next = nullptr;
        infile.open(filename, ios::in | ios::_Nocreate); //打开须统计的字符文件
        if (!infile)  //判断打开是否正常
        {
            cout << "文件" << filename << "打开失败!" << endl;
            exit(1);
        }
        while (infile.get(a))  //一个一个读入字符,直到文件尾
        {
            pt = L->next;
            while (pt != nullptr)
            {
                if (pt->nm == a)   //如果当前结点符号与读入符号相同,累积出现的次数
                {
                    pt->freq++;
                    break;
                }
                pt = pt->next;
            }
            if (pt == nullptr)  //属于新出现的符号,建立新结点,保存其出现频率
            {
                pt = new countfreqnode;
                pt->next = nullptr;
                L->next = pt;
                pt->nm = a;
                pt->freq = 1;
            }
            cout << a;
        }
        cout << endl;
        pt = L->next;  //输出每个符号出现的频率
        cout << setw(10) << "符号" << setw(10) << "频率" << endl;
        while ( pt!=nullptr )
        {
            cout << setw(10) << pt->nm << setw(10) << pt->freq << endl;
            pt = pt->next;
        }
        infile.close();
        return L;  //返回保存每个符号出现频率的链表指针
}

//获取链表的长度
int ListLength(countfrelist L)
{
    if (L->next == NULL)
        return 0;
    int length = 0;
    countfreqnode *p = L->next;
    while (p->next != NULL)
    {
        p = p->next; length++;
    }
    return length;
}

//选择数组中最小的两个元素

void selecttwomin(huffmannode* &HT, int len, int &s1, int &s2)
{
    int i;
    for (i = 0; i <=len && HT[i].parent != 0; i++);
    s1 = i;
    for (i = 0; i <= len; i++)
        if (HT[i].parent == 0 && HT[i].weight<HT[s1].weight)
            s1 = i;
    for (i = 0; i <= len; i++)
        if (HT[i].parent == 0 && i != s1)
            break;
    s2 = i;
    for (i = 0; i <= len; i++)
        if (HT[i].parent == 0 && i != s1 && HT[i].weight<HT[s2].weight)
            s2 = i;
}

//构建Huffman树并且获取编码
huffmannodetree huffmantree(countfrelist &tm, int l){
    int n,i,fmin,smin;
    countfreqnode*p;
    n = 2 * l - 1;
    huffmannodetree ht = new huffmannode[n];
    p =tm->next;
    //将链表中的数据转移到数组中来
    for (i = 0; i < l && p!=NULL; ++i,p=p->next)
    {
        ht[i].weight = p->freq;
        ht[i].ch = p->nm;
        ht[i].parent = ht[i].lchild = ht[i].rchild = 0;
    }
    for (; i < n; ++i)
    {
        ht[i].weight = 0;
        ht[i].ch = '';
        ht[i].parent = ht[i].lchild = ht[i].rchild = 0;
    }
    //建造huffman树
    for (i = l; i <n; ++i)
    {
        selecttwomin(ht, i-1, fmin, smin);
        ht[fmin].parent = i; ht[smin].parent = i;
        ht[i].lchild = fmin; ht[i].rchild = smin;
        ht[i].weight = ht[fmin].weight + ht[smin].weight;
    }
    //获取编码
    for (i = 0; i < l; ++i)
    {
        int start = l - 1;
        ht[i].code[start] = '';
        int c, f;
        for (c = i, f = ht[i].parent; f != 0; c = f, f = ht[f].parent)
        {
            if (ht[f].lchild == c)
                ht[i].code[--start] = '0';
            else ht[i].code[--start] = '1';
        }
        ht[i].index = start;
    }
    return ht;
}

//译码

void decode(huffmannodetree & ht,int l){
    char infilename[20];
    char outfilename[20];
    char a_code[20] = "";
    ifstream infile;
    char a;
    int c=0;
    cout << "input the filename which translate" << endl;
    cin >> infilename;
    infile.open(infilename, ios::in | ios::_Nocreate);
    if (!infile)
    {
        cout << "文件" << infilename << "打开失败!" << endl;
        exit(1);
    }
    ofstream outfile;
    strcat_s(outfilename, infilename);
    outfile.open(outfilename, ios::out);
    if (!outfile)
    {
        cout << "文件" << outfilename << "打开失败!" << endl;
        exit(1);
    }
    while (infile.get(a))
    {
        if ('0' == a)
            strcat_s(a_code, "0");
        else
            strcat_s(a_code, "1");
        while (c < l)
        {

            if (0 == strcmp(a_code, &ht[c].code[ht[c].index]))
            {
                outfile << ht[c].ch;
                strcpy_s(a_code, "");
                break;
            }
            else
                c++;
        }
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    char filename[30];
    int len;
    countfrelist L;
    huffmannodetree ht;
    cout << "请输入待统计的文件名:";
    cin >> filename;
    L = counthelp(filename);
    len = ListLength(L);
    ht = huffmantree(L, len);
    decode(ht, len);
    system("pause");
    return 0;
}

解决方案

我看你代码有不少打印语句。
给一个建议,输入文件路径结束后,首先打印下该文件路径。确定下是否正确。
后期代码调试:
1. 使用单步调试
2. 或者在某些地方加上打印语句,看是否有输出,确定代码错误的位置

解决方案二:

仔细调试下,特别是指针。注意要调试而不是运行,这样错了才会停在错误的行上。

时间: 2024-10-30 14:48:58

c++-Huffman树的问题,输入要统计的文件就闪掉的相关文章

编码-霍夫曼树程序,输入字符串统计字符出现次数并译码。请问如何改成从文件读入字符串?

问题描述 霍夫曼树程序,输入字符串统计字符出现次数并译码.请问如何改成从文件读入字符串? //生成HuffmanCode文件的两个函数void HuffmanEncoding(HuffmanTree HTHuffmanCode HC){//根据HuffmanTreeHT求HuffmanCode表HC int cpi; char cd[n]; int start; cd[num] = ''; for(i = 1;i <= num;i++){ start = num; c = i; while((p

Huffman树进行编码和译码

//编码 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> #include<fstream> #include<map> using namespace std; typedef struct HuffmanNode{ int w;//节点的权值

我在用C#写一个huffman编码的窗体程序,但是在遍历huffman树的时候进入了死循环,我看了一下午没找到答案

问题描述 希望高手能够指点一下!谢了... form1.csusingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Windows.Forms;usingSystem.Collections;namespaceAL_4{publicpartialc

搜狗输入法输入字数统计查看方法

  现在,搜狗输入法是可以查看自己每天输入的字数的,即输入字数统计.那么搜狗输入法输入字数统计在哪,搜狗输入法字数统计排名怎么看,下面小编就给大家带来详细的介绍. 右击搜狗输入法; 点击输入统计,就可以看到自己的累计输入字数了; 你也可以点击今日输入,查看今天输入字数统计; 如果你登陆了搜狗输入法,还可以查看好友排名.

搜狗输入法输入字数统计在哪

  搜狗输入法数字统计可以显示统计你每天输入的字数,而且如果你使用qq账户登录还可以查看好友之间使用搜狗输入法输入字数排名,那么搜狗输入法输入字数统计在哪,搜狗输入法字数统计排名怎么看,下面小编就给大家带来详细的介绍. 右击搜狗输入法 点击输入统计,就可以看到自己的累计输入字数了 你也可以点击今日输入,查看今天输入字数统计 如果你登陆了搜狗输入法,还可以查看好友排名

c++-C++,huffman树编码的压缩软件输出到txt的问题

问题描述 C++,huffman树编码的压缩软件输出到txt的问题 string line; while(getline(ifsa2,line)) { for(int m=0;m<line.length();m++) { //cout<<line[m]; if(line[m]!=' ') { for(int i=0;i<leafs.size();i++) { if(leafs[i].data==line[m]) { break; } } for(int j=0;j<tree.

用ASP.NET然后实现信息的输入及统计

问题描述 用ASP.NET然后实现信息的输入及统计 解决方案 解决方案二:这也太笼统了吧--解决方案三:高手就是录入一些客户的基本信息(年龄,单位,类型.....)然后在按时间分类统计每个人录入了多少,要精确到信息种类解决方案四:还是笼统..下手干吧.哪里不会了再来这里发.垃圾贴解决方案五:用javascript和DHTML结合了做,不需要刷新,主要用parentchild和nodeschild

搜狗输入法输入字数统计功能在哪

有时我们希望统计一下输入数字了,那么输入数字统计功能在哪里进入呢,对于这个问题我们来看看. 在电脑右下角右击"搜狗输入法"如下图所示 好了然后在进入之后点击输入统计,就可以看到自己的累计输入字数了,细节如下图所示 你也可以点击今日输入,查看今天输入字数统计 如果你登陆了搜狗输入法,还可以查看好友排名 其实总得来讲数字统计功能的使用方法也就到此了,其实此功能作用不大了,我只是为各位介绍好玩了,希望文章能够帮助到各位.

基于Huffman编码的C语言压缩和解压缩文件程序

问题描述 基于Huffman编码的C语言压缩和解压缩文件程序 基于Huffman编码的C语言解压缩和解压缩文件程序文件程序. c功底比较差...一下午只写出了huffman树. 想求能直接调试的代码.最好有注释. 解决方案 基于Huffman编码的C语言解压缩文件程序Huffman 编码压缩 解决方案二: http://www.linuxidc.com/Linux/2014-08/105672.htm 解决方案三: 为什么不用自适应算数编码呢?效果要比霍夫曼好多了吧! 解决方案四: 为什么不用自