问题描述
- 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