哈弗曼树的问题,代码如下,求详细解释。答辩需要,但我一点也不懂,急求

int Count(int cou[]) //计算输入的字母的个数
{
char word;
char letter[27]={' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', 'p','q','r','s','t','u','v','w','x','y','z'};
fstream SourceFile;
SourceFile.open("SourceFile.txt",ios::in); //从SourceFile.txt读取
if (!SourceFile)
{
cout<<"Can't open this file"<<endl;
}
while (!SourceFile.eof())//循环直到文件结束

    {
        SourceFile.get(word);
        if (word>='A'&&word<='Z')//如果是大写字母,统一转换为小写
        {
            word=word+32;//32是 'a' - 'A' ascii差
        }
        int i=word-96;// 96是'a'的ascii
        cou[i]++; // cou保存你对应字母的统计数字,+1
    }
    SourceFile.close();//关闭文件
    cout<<"letter"<<'\t'<<'\t'<<"频率为"<<endl;//输出
        for (int j=1;j<=26;j++)//依次输出a~z字符的出现频率
        {
            if (cou[j]!=0)//如果没有这个字母出现,就不输出
            {
                cout<<letter[j]<<'\t'<<'\t'<<cou[j]<<endl; //letter[j]可以用 (char)('A' + i) 代替
            }
        }
        cout<<"读入完事儿!"<<endl;

return 0;

}

/*-----------选择HT中双亲域为0的权值最小的两个结点--------------*/
void Select(HuffmanTree HT,int i,int &s1,int &s2) //自定义函数
{
//选择两个最小值,将他们的位序输出到s1,s2
int m=0,k=0;

for(k=1;k<=n;++k)            //得到第一个父节点为零的节点,++k先自加,再运算
{
    if(0==HT[k].parent)
    {
        m=HT[k].weight;
        s1=k;
        break;
    }
}

for(;k<=n;++k)                    //得到最小值
{
    if(0==HT[k].parent && HT[k].weight<m)    //权<m
    {
        m=HT[k].weight;
        s1=k;
    }
}

for(k=1;k<=n;++k)                //得到第二个父节点为零的节点
{
    if(k!=s1 && 0==HT[k].parent)
    {
        m=HT[k].weight;
        s2=k;
        break;
    }
}

for(;k<=n;++k)                    //求得次小元
{
    if(0==HT[k].parent && k!=s1 && HT[k].weight<m)
    {
        m=HT[k].weight;
        s2=k;
    }
}

}//Select

/*---------算法5.10 根据统计结果建立Huffman树-----------*/
void CreatHuffmanTree(HuffmanTree &HT,int cou[])
{ if(n<=1) return;
int m=2*n-1;
HT=new HTNode[m+1]; //0 号单元未用,所以需要动态分配m+1个单元,HT[m]表示根节点
int s1=0,s2=0; //

for(int i=1;i<=m;i++)           //初始化HuffmanTree 将1~m单元中的双亲,左右孩子的下标初始化为0
{
    HT[i].lchild=0;
    HT[i].rchild=0;
    HT[i].parent=0;
}

for(i=1;i<=n;i++)               //输入叶节点的权值
    HT[i].weight=cou[i-1];      
for(i=n+1;i<=m;i++)             
{
    Select(HT,i,s1,s2);         //选择HT中两个双亲域为0且权值最小的两个节点的序号s1和s2
    HT[s1].parent=i;    HT[s2].parent=i;       //标记其双亲结点为HT[i]
    HT[i].lchild=s1;    HT[i].rchild=s2;       //HT[s1]和HT[s2]作为HT[i]的左右孩子
    HT[i].weight=HT[s1].weight+HT[s2].weight;   //HT[i]的权值为左右孩子权值之和
}
cout<<"huffmantree构造完成"<<endl;

}

/*--------------------算法5.11 根据统计结果对各字符进行编码,并保存在Code.txt中------------------*/
void CreatHuffmanCode(HuffmanTree HT,HuffmanCode &HC)
{ int start;
char cd;
HC=new char
[n+1];
cd=new char[n];
cd[n-1]='\0';
int i,c,f;
for (i=1;i<=n;++i)
{
start=n-1;
c=i;f=HT[i].parent;
while(f!=0){
--start;
if (HT[f].lchild==c)
cd[start]='0';
else cd[start]='1';
c=f;
f=HT[f].parent;
}
HC[i]=new char[n-start];
strcpy(HC[i],&cd[start]);
}
delete cd;
cout<<"HuffmanCode创建完毕"<<endl;
}

/*----------对SourceFile.txt进行编码,并保存在ResultFile.txt中-----------*/
void Code(HuffmanTree &HT,HuffmanCode &HC)
{
string alph;
ifstream infile("SourceFile.txt");
if(!infile){
cout<<"Cannot open this file!"< exit(1);
}
infile>>alph;
infile.close();
ofstream outfile;
outfile.open("ResultFile.txt");
if(!outfile)
cout<<"cannot open the file!"<<endl;
else{
for(int i=0;i<alph.length();i++){
int j=alph[i]-97;
for(int k=1;k<=n;k++){
if(HT[k].weight==cou[j])
outfile<<HC[k];
}
}
}
cout<<"huffman编码完成"<<endl;
outfile.close();
}

2个回答

之前的问题如果满意,请先采纳。然后帮你看剩余的部分。

Deadwood_
Deadwood_ 谢谢你,我这是要答辩的题目,但不懂这些代码什么意思,能再详细一些吗,再不懂的我可以百度
大约 3 年之前 回复
 /*--------------------算法5.11 根据统计结果对各字符进行编码,并保存在Code.txt中------------------*/
void CreatHuffmanCode(HuffmanTree HT,HuffmanCode &HC)
{ int start;
char cd;
HC=new char[n+1]; //生成长度为n+1个字符的哈夫曼编码表
cd=new char[n]; //这里写错了吧,是char * cd
cd[n-1]='\0'; //最后一个字符设置为\0,也就是字符串结束
int i,c,f;
for (i=1;i<=n;++i) //遍历整个哈夫曼编码表
{
start=n-1;
c=i;f=HT[i].parent; //子节点的值等于它父节点的值的和
while(f!=0){
--start;
if (HT[f].lchild==c) //如果左子节点没有
cd[start]='0'; //添加前缀码
else cd[start]='1'; 。。输出1
c=f;
f=HT[f].parent; .//获取上一层节点
}
HC[i]=new char[n-start]; //构造哈夫曼编码
strcpy(HC[i],&cd[start]); //复制到参数中作为结果输出
}
delete cd;
cout<<"HuffmanCode创建完毕"<<endl;
}
/*----------对SourceFile.txt进行编码,并保存在ResultFile.txt中-----------*/
void Code(HuffmanTree &HT,HuffmanCode &HC)
{
string alph; //子母表
ifstream infile("SourceFile.txt"); //读取文件
if(!infile){
cout<<"Cannot open this file!"< exit(1);
}
infile>>alph;
infile.close();
ofstream outfile;
outfile.open("ResultFile.txt");
if(!outfile)
cout<<"cannot open the file!"<<endl;
else{
for(int i=0;i<alph.length();i++){
int j=alph[i]-97; //当前字符下标
for(int k=1;k<=n;k++){
if(HT[k].weight==cou[j]) //设置哈夫曼树的权重
outfile<<HC[k]; //输出到文件
}
}
}
cout<<"huffman编码完成"<<endl;
outfile.close();
}
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
C语言哈弗曼树编码,求大神帮我改一下
这是原题和代码,有些错误,运行不出来,求大神帮我改改 实现一个哈夫曼编码系统,系统包括以下功能: (1) 字符信息统计:读取待编码的源文件SourceFile.txt,统计出现的字符及其频率。 (2) 建立哈夫曼树:根据统计结果建立哈夫曼树。 (3) 建立哈夫曼码表:利用得到的哈夫曼树,将各字符对应的编码表保存在文件Code.txt中。 (4) 对源文件进行编码:根据哈夫曼码表,将SourceFile.txt中的字符转换成相应的编码文件ResultFile.txt。 代码 #include<stdio.h> #include<fstream> #include<iostream> using namespace std; int Count(int cou[]) //计算输入的字母的个数 { std fstream SourceFile; char word; char letter[27]={' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', 'p','q','r','s','t','u','v','w','x','y','z'}; // fstream SourceFile; SourceFile.open("SourceFile.txt",ios::in); if (!SourceFile) { cout<<"Can't open0 this file"<<endl; } while (!SourceFile.eof()) { SourceFile.get(word); if (word>='A'&&word<='Z') { word=word+32; } int i=word-96; cou[i]++; } SourceFile.close(); cout<<"letter"<<'\t'<<'\t'<<"频率为"<<endl; for (int j=1;j<=26;j++) { if (cou[j]!=0) { cout<<letter[j]<<'\t'<<'\t'<<cou[j]<<endl; } } cout<<"读入完事儿!"<<endl; return 0; } /*-----------选择HT中双亲域为0的权值最小的两个结点--------------*/ void Select(HuffmanTree HT,int i,int &s1,int &s2) { //选择两个最小值,将他们的位序输出到s1,s2 int m=0,k=0; for(k=1;k<=n;++k) //得到第一个父节点为零的节点 { if(0==HT[k].parent) { m=HT[k].weight; s1=k; break; } } for(;k<=n;++k) //得到最小值 { if(0==HT[k].parent && HT[k].weight<m) { m=HT[k].weight; s1=k; } } for(k=1;k<=n;++k) //得到第二个父节点为零的节点 { if(k!=s1 && 0==HT[k].parent) { m=HT[k].weight; s2=k; break; } } for(;k<=n;++k) //求得次小元 { if(0==HT[k].parent && k!=s1 && HT[k].weight<m) { m=HT[k].weight; s2=k; } } }//Select /*---------算法5.10 根据统计结果建立Huffman树-----------*/ void CreatHuffmanTree(HuffmanTree &HT,int cou[]) { if(n<=1) return; int m=2*n-1; HT=new HTNode[m+1]; //0 号单元未用,所以需要动态分配m+1个单元,HT[m]表示根节点 int s1=0,s2=0; // for(int i=1;i<=m;i++) //初始化HuffmanTree 将1~m单元中的双亲,左右孩子的下标初始化为0 { HT[i].lchild=0; HT[i].rchild=0; HT[i].parent=0; } for(i=1;i<=n;i++) //输入叶节点的权值 HT[i].weight=cou[i-1]; for(i=n+1;i<=m;i++) { Select(HT,i,s1,s2); //选择HT中两个双亲域为0且权值最小的两个节点的序号s1和s2 HT[s1].parent=i; HT[s2].parent=i; //标记其双亲结点为HT[i] HT[i].lchild=s1; HT[i].rchild=s2; //HT[s1]和HT[s2]作为HT[i]的左右孩子 HT[i].weight=HT[s1].weight+HT[s2].weight; //HT[i]的权值为左右孩子权值之和 } cout<<"huffmantree构造完成"<<endl; } /*--------------------算法5.11 根据统计结果对各字符进行编码,并保存在Code.txt中------------------*/ void CreatHuffmanCode(HuffmanTree HT,HuffmanCode &HC) { int start; char *cd; HC=new char*[n+1]; cd=new char[n]; cd[n-1]='\0'; int i,c,f; for (i=1;i<=n;++i) { start=n-1; c=i;f=HT[i].parent; while(f!=0){ --start; if (HT[f].lchild==c) cd[start]='0'; else cd[start]='1'; c=f; f=HT[f].parent; } HC[i]=new char[n-start]; strcpy(HC[i],&cd[start]); } delete cd; cout<<"HuffmanCode创建完毕"<<endl; } /*----------对SourceFile.txt进行编码,并保存在ResultFile.txt中-----------*/ void Code(HuffmanTree &HT,HuffmanCode &HC) { string alph; ifstream infile("SourceFile.txt"); if(!infile){ cout<<"Cannot open this file!"<<endl; exit(1); } infile>>alph; infile.close(); ofstream outfile; outfile.open("ResultFile.txt"); if(!outfile) cout<<"cannot open the file!"<<endl; else{ for(int i=0;i<alph.length();i++){ int j=alph[i]-97; for(int k=1;k<=n;k++){ if(HT[k].weight==cou[j]) outfile<<HC[k]; } } } cout<<"huffman编码完成"<<endl; outfile.close(); }
新手哈弗曼树访问出错求大神改一下
#include<iostream>#include"stdio.h"#include<string>#include<conio.h>#include<fstream>#include <vector>using namespace std;const int Ml = 10;const int Mv = 10;const int Mn = Ml * 2 - 1;const int Mb = 100;typedef struct { string s; int weight; int parent; int lchild; int rchild; string code;}HNodeType;struct assist{ int weight; int num; };HNodeType *HaffmanTree(int n, HNodeType HuffNode[]){ int i, j, N; N = n; for (i = 0; i<2 * n - 1; i++){ /*HuffNode[i].s = '0';*/ HuffNode[i].weight = 0; HuffNode[i].parent = -1; HuffNode[i].lchild = -1; HuffNode[i].rchild = -1; HuffNode[i].code = '1'; } cout << "请输入" << n << "个权值:" << endl; for (i = 0; i<n; i++){ cin >> HuffNode[i].weight; //输入n个叶子结点的权值 } ofstream outfile; outfile.open("e:\\hftree.dat"); if (!outfile){ cerr << "打开文件失败!" << endl; return 0; } cout << "请输入" << n << "个字符:" << endl; string str; getchar(); getline(cin, str,'\n'); for (i = 0; i < n; i++){ HuffNode[i].s = str[i]; } outfile << str; outfile.close(); int temp; string temp2; for (j = 0; j < n - 1; j++){ for (i = 0; i < n - 1; i++){ if (HuffNode[i].weight<HuffNode[i + 1].weight){ temp = HuffNode[i].weight; HuffNode[i].weight = HuffNode[i + 1].weight; HuffNode[i + 1].weight = temp; temp2 = HuffNode[i].s; HuffNode[i].s = HuffNode[i + 1].s; HuffNode[i + 1].s = temp2; } } } for (i = 0; i < n - 1; i++)//code赋值 {HuffNode[i].code = '0';} //------------------------------------------------------------------------------------ assist a[Mn]; int m; assist temp3; for (m = 0; m<n - 1; m++){ a[m].weight = HuffNode[m].weight; a[m].num = m; } while (m>=1){ HuffNode[n].weight = a[m].weight + a[m - 1].weight; HuffNode[n].lchild = a[m - 1].num; HuffNode[n].rchild = a[m].num; HuffNode[a[m].num].parent = n; HuffNode[a[m - 1].num].parent = n; m--; a[m].weight = HuffNode[n].weight; a[m].num = n; n++; for (j = 0; j <= m; j++){ for (i = 0; i <= m; i++){ if (a[i].weight < a[i + 1].weight){ temp3 = a[i]; a[i] = a[i + 1]; a[i + 1] = temp3; } } } } //-------------------------------------------------------------------------------- /*for (i = n - 1; i > 0; i--, n++){ HuffNode[n].weight = HuffNode[n - 1].weight + HuffNode[i - 1].weight; HuffNode[n].rchild = n - 1; HuffNode[n].lchild = i - 1; HuffNode[n - 1].parent = n; HuffNode[i - 1].parent = n; }*/ cout << "哈弗曼树结构:" << endl; for (i = 0; i < 7; i++) cout << HuffNode[i].code << '\t' << HuffNode[i].s << '\t' << HuffNode[i].weight << '\t' << HuffNode[i].lchild << '\t' << HuffNode[i].rchild << '\t' << HuffNode[i].parent << endl; return HuffNode;}void Hfcode(HNodeType a[],int n){ vector <string> cd(n);//叶子节点编码 int i = 0; while (i != n){ int b = 1; int j = a[0].parent; while(b<=i){ j = a[j].rchild; cd[i] += a[j].code; b++; } if(a[j].lchild!=-1) cd[i] += '0'; else cd[i] += '1'; i++; } ofstream outfile; outfile.open("e:\\hfcode.dat"); if (!outfile){ cerr << "打开文件失败!" << endl; } for (i = 0; i < n; i++){ outfile << cd[i]; } outfile.close();}void Translate(HNodeType a[],int n){ ifstream infile; string ss; infile.open("e:\\hfcode.dat"); infile >> ss; //cout << ss; infile.close(); cout << '\n' << "从e:\\hfcode.dat中获取编码串为:" << ss << ",将其译码:" << '\n' << endl; cout << "字符编码" << '\t' << "译码" << endl; int i = 0, m = ss.size(), j = a[0].parent; while (i<m-1){ cout << ss[i]; if (ss[i] == '0'){ j = a[j].lchild; cout <<'\t'<<'\t'; cout << a[j].s << endl; j=a[0].parent; } if (ss[i] == '1'){ j = a[j].rchild; if (a[j].rchild==-1){ cout << '\t' << '\t'; cout << a[j].s << endl; } } i++; }}int main(){ int n; cout << "输入叶子节点的个数" << endl; cin >> n; HNodeType HuffNode[Mn]; HaffmanTree(n, HuffNode); Hfcode(HuffNode, n); Translate(HuffNode,n); _getch();}
计算输入字母的个数,代码如下,求详细解释
int Count(int cou[]) //计算输入的字母的个数 { char word; char letter[27]={' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', 'p','q','r','s','t','u','v','w','x','y','z'}; fstream SourceFile; SourceFile.open("SourceFile.txt",ios::in); if (!SourceFile) { cout<<"Can't open this file"<<endl; } while (!SourceFile.eof()) { SourceFile.get(word); if (word>='A'&&word<='Z') { word=word+32; } int i=word-96; cou[i]++; } SourceFile.close(); cout<<"letter"<<'\t'<<'\t'<<"频率为"<<endl; for (int j=1;j<=26;j++) { if (cou[j]!=0) { cout<<letter[j]<<'\t'<<'\t'<<cou[j]<<endl; } } cout<<"读入完事儿!"<<endl; return 0; }
哈弗曼树为什么第二个和第四个节点会交换,请帮忙看看代码
#include<iostream> using namespace std; typedef struct { int Weight; bool paixflag; bool flag; int par; int lch; int rch; }HuffNode,*pHuffNode; typedef struct { int n; int root; HuffNode *Huf; }HuffTree,*pHuffTree; HuffTree * InitHuffman(int w[],int n){ if(n<0) return NULL; HuffTree *Tree = new HuffTree(); Tree->n = n; Tree->Huf = new HuffNode[2*n-1]; for(int i=0;i<2*n-1;i++){ Tree->Huf[i].flag = 0; Tree->Huf[i].lch = -1; Tree->Huf[i].rch = -1; Tree->Huf[i].par = -1; Tree->Huf[i].Weight = (i<n)?w[i]:999999; } return Tree; } void GetSmallTwo(HuffNode *Num,int n,int &m1,int &m2){//每次取得新数组的两个flag为0的最小值 for(int i=0;i<2*n-1;i++){ for(int j=i+1;j<2*n-1;j++){ if(Num[i].Weight>Num[j].Weight){ int temp = Num[i].Weight; Num[i].Weight = Num[j].Weight; Num[j].Weight = temp; } } } for(int i=0;i<2*n-1;i++){ if(Num[i].flag==0){ m1 = Num[i].Weight; m2 = Num[i+1].Weight; break; } } } HuffTree* CreateHuffman(int w[],int n){ HuffTree *HTree = InitHuffman(w,n); int i = 0,j = 0,m1 = 0,m2 = 0,x1,x2; for(i=0;i<n-1;i++){ GetSmallTwo(HTree->Huf,n,m1,m2); x1 = 0;x2 = 0; for(j=0;j<n+i;j++){ if(!HTree->Huf[j].flag){ if(HTree->Huf[j].Weight==m1){ x1 = j; cout<<endl<<"x1-->"<<x1<<endl; }else if(HTree->Huf[j].Weight==m2){ x2 = j; cout<<endl<<"x2-->"<<x2<<endl; } } } HTree->Huf[x1].par = n+i; HTree->Huf[x2].par = n+i; HTree->Huf[x2].flag = 1; HTree->Huf[x1].flag = 1; HTree->Huf[n+i].Weight = HTree->Huf[x1].Weight+HTree->Huf[x2].Weight; HTree->Huf[n+i].lch = x1; HTree->Huf[n+i].rch = x2; } return HTree; } int main(){ int num[7] = {3,1,7,5}; HuffTree *Tree = /*InitHuffman(num,10);//*/CreateHuffman(num,4); cout<<"[K]"<<"Weight "<<"LRCHIL "<<"RRCHIL "<<"PARENT "<<"flag "<<endl; for(int i=0;i<7;i++){ cout<<"["<<i<<"] "<<Tree->Huf[i].Weight<<" "<<Tree->Huf[i].lch<<" "<<Tree->Huf[i].rch<<" "<<Tree->Huf[i].par<<" "<<Tree->Huf[i].flag<<endl; } /*for(int i=0;i<10;i++){ cout<<cout<<"HTree->Huf["<<i<<"].Weight-->"<<Tree->Huf[i].Weight<<endl; cout<<i<<"--->flag"<<Tree->Huf[i].flag<<endl; cout<<i<<"--->son"<<Tree->Huf[i].lch<<endl; } int m1,m2; GetSmallTwo(Tree->Huf,10,m1,m2); cout<<m1<<" "<<m2<<endl; GetSmallTwo(Tree->Huf,10,m1,m2); cout<<m1<<" "<<m2<<endl; GetSmallTwo(Tree->Huf,10,m1,m2); cout<<m1<<" "<<m2<<endl; GetSmallTwo(Tree->Huf,10,m1,m2); cout<<m1<<" "<<m2<<endl; GetSmallTwo(Tree->Huf,10,m1,m2); cout<<m1<<" "<<m2<<endl; for(int i=0;i<10;i++){ cout<<cout<<"HTree->Huf["<<i<<"].Weight-->"<<Tree->Huf[i].Weight<<endl; cout<<i<<"--->flag"<<Tree->Huf[i].flag<<endl; cout<<i<<"--->son"<<Tree->Huf[i].lch<<endl; }*/ system("pause"); return 0; }
C++哈夫曼编码译码器设计与实现并对哈夫曼树进行先序遍历。
现在就是差一个先序遍历的要求没有做到 ``` #include<stdio.h> #include<string.h> #include<stdlib.h> //树结点定义 typedef struct { int weight; int parent; int lchild; int rchild; }HTNode,*HuffmanTree; static char N[100];//用于保存正文 //哈弗曼编码,char型二级指针 typedef char **HuffmanCode; //封装最小权结点和次小权结点 typedef struct { int s1; int s2; }MinCode; //函数声明 void Error(char *message); HuffmanCode HuffmanCoding(HuffmanTree &HT,HuffmanCode HC,int *w,int n); MinCode Select(HuffmanTree HT,int n); //当输入1个结点时的错误提示 void Error(char *message) { fprintf(stderr,"Error:%s\n",message); //根据指定的格式,向输出流写入数据 exit(1); } //构造哈夫曼树HT,编码存放在HC中,w为权值,n为结点个数 HuffmanCode HuffmanCoding(HuffmanTree &HT,HuffmanCode HC,int *w,int n) { int i,s1=0,s2=0; HuffmanTree p; char *cd; int f,c,start,m; MinCode min; if(n<=1) { Error("Code too small!");//只有一个结点不进行编码,直接exit(1)退出。 } m=2*n-1;//哈弗曼编码需要开辟的结点大小为2n-1 HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//开辟哈夫曼树结点空间 m+1 ,动态内存分配。 //初始化n个叶子结点,w[0] = 0,main函数已赋值 for(p=HT,i=0;i<=n;i++,p++,w++) { p->weight=*w; p->parent=0; p->lchild=0; p->rchild=0; } //将n-1个非叶子结点的初始化 for(;i<=m;i++,p++) { p->weight=0; p->parent=0; p->lchild=0; p->rchild=0; } //构造哈夫曼树 for(i=n+1;i<=m;i++) { min=Select(HT,i-1);//找出最小和次小的两个结点 s1=min.s1 ; //最小结点下标 s2=min.s2;//次小结点下标 HT[s1].parent=i; HT[s2].parent=i; HT[i].lchild=s1; HT[i].rchild=s2; HT[i].weight=HT[s1].weight+HT[s2].weight; } //打印哈弗曼树 printf("HT List:\n"); printf("Number\t\tweight\t\tparent\t\tlchild\t\trchild\n"); for(i=1;i<=m;i++) { printf("%d\t\t%d\t\t%d\t\t%d\t\t%d\t\n",i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild); } //从叶子结点到根节点求每个字符的哈弗曼编码 HC=(HuffmanCode)malloc((n+1)*sizeof(char *)); cd=(char *)malloc(n*sizeof(char *));//为哈弗曼编码动态分配空间 cd[n-1]='\0';//如:3个结点编码最长为2。cd[3-1] = '\0'; //求叶子结点的哈弗曼编码 for(i=1;i<=n;i++) { start=n-1; //定义左子树为0,右子树为1 /* 从最下面的1号节点开始往顶部编码(逆序存放),然后编码2号节点,3号...... */ for(c=i,f=HT[i].parent; f!=0; c=f,f=HT[f].parent) { if(HT[f].lchild==c) cd[--start]='0'; else cd[--start]='1'; } //为第i个字符分配编码空间 HC[i]=(char *)malloc((n-start)*sizeof(char *)); //将当前求出结点的哈弗曼编码复制到HC strcpy(HC[i],&cd[start]); } free(cd); return HC; } MinCode Select(HuffmanTree HT,int n) { int min,secmin; int temp = 0; int i,s1,s2,tempi = 0; MinCode code ; s1=1; s2=1; min = 9999; //找出权值最小的结点,下标保存在s1中 for(i=1;i<=n;i++) { if(HT[i].weight<min && HT[i].parent==0) { min=HT[i].weight; s1=i; } } secmin = 9999; //找出权值次小的结点,下标保存在s2中 for(i=1;i<=n;i++) { if((HT[i].weight<secmin) && (i!=s1) && HT[i].parent==0) { secmin=HT[i].weight; s2=i; } } //放进封装中 code.s1=s1; code.s2=s2; return code; } void HuffmanTranslateCoding(HuffmanTree HT, int n,char* ch) {//译码过程 int m=2*n-1; int i,j=0; printf("After Translation:"); while(ch[j]!='\0')//ch[]:你输入的要译码的0101010串 { i=m; while(0 != HT[i].lchild && 0 != HT[i].rchild)//从顶部找到最下面 { if('0' == ch[j])//0 往左子树走 { i=HT[i].lchild; } else//1 往右子树走 { i=HT[i].rchild; } ++j;//下一个路径 } printf("%c",N[i-1]);//打印出来 } printf("\n"); } void main() { HuffmanTree HT=NULL; HuffmanCode HC=NULL; int *w=NULL; int i,n; char tran[100]; printf("Input N(char):"); gets(N); fflush(stdin); n = strlen(N); w=(int *)malloc((n+1)*sizeof(int *));//开辟n+1个长度的int指针空间 w[0]=0; printf("Enter weight:\n"); //输入结点权值 for(i=1;i<=n;i++) { printf("w[%d]=",i); scanf("%d",&w[i]); } fflush(stdin); //清空输入缓冲区 //构造哈夫曼树HT,编码存放在HC中,w为权值,n为结点个数 HC=HuffmanCoding(HT,HC,w,n); //输出哈弗曼编码 printf("HuffmanCode:\n"); printf("Number\t\tWeight\t\tCode\n"); for(i=1;i<=n;i++) { printf("%c\t\t%d\t\t%s\n",N[i-1],w[i],HC[i]); } fflush(stdin); //译码过程 printf("Input HuffmanTranslateCoding:"); gets(tran); HuffmanTranslateCoding(HT, n, tran); return; } ```题目要求:九、哈夫曼编码译码器设计与实现 编写程序设计哈夫曼编码译码器。 (1)根据输入的权值建立哈夫曼树。 (2)对建立好的哈夫曼树进行先序遍历。 (3)利用建好的哈夫曼树生成哈夫曼编码,并显示生成的各字符的哈夫曼编码。 (4)根据输入的字符进行译码。 (5)显示功能:以先序遍历的顺序显示建立好的哈夫曼树。显示哈夫曼编码和译码的结果。
哈弗曼进行译码的时候怎么最后得到的是原来编码前的短文顺序,跪求指点
哈弗曼进行译码的时候怎么最后得到的是原来编码前的短文顺序,跪求指点
修改程序:信源编解码(c语言)
修改程序:问题1。源文件source文本空间太长汉字太多无法运行2,未按频度要求排序 问题描述: 信源编解码是通信系统的重要组成部分。本实验旨在通过程序设计实现基于哈夫曼编码的信源编解码算法。程序具备以下功能: 对于给定的源文档 SourceDoc.txt, 1) 统计其中所有字符的频度(某字符的频度等于其出现的总次数除以总字符数) , 包括字母(区分大小写) 、标点符号及格式控制符(空格、回车等) 。 2) 按频度统计结果生成哈夫曼编码码表。 3) 基于哈夫曼码表进行编码,生成对应的二进制码流,并输出到文件 Encode.dat。 4) 对二进制码流进行哈夫曼解码,把结果输出到文件 DecodeDoc.txt。 5) 判断DecodeDoc.txt与SourceDoc.txt内容是否一致,以 验证编解码系统的正确性。 要求: 1) 用 C 语言实现。 2) 用子函数实现各功能模块。 3) 输出文件 Statistic.txt,包含的信息有:按频度大小排序的字符表,及各字符出现 的次数、频度及哈夫曼编码。 4) 应至少包含链表、二叉树的数据结构。 5) 不能用冒泡排序算法。 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/stat.h> #include<sys/types.h> #include<fcntl.h> #include<unistd.h> #include<errno.h> #define N 10000 int count = 0; //每增加一个新的字符, count增加1, 可表示a中的字符种类数, 也即哈夫曼树叶子点个数 /*定义哈夫曼树结构体*/ typedef struct HuffmanTree{ int weight; int parent; int Lchild; int Rchild; }HuffmanTree[2*N]; /*定义储存字符及其出现次数的结构体*/ typedef struct DifferentCharacter{ char char_date; int num; //相同字符出现的次数 char a_code[100]; //每种字符对应的编码 }difcha[N]; /*在一定范围内选择两个weight最小的结点, 并将两个结点的序号赋给s1, s2*/ void select_two(HuffmanTree ht, int j, int *s1, int *s2) { int i = 1, temp; int min1 = 0, min2 = 0; while( (ht[i].parent != 0) && (i <= j) ) i++; *s1 = i; min1 = ht[i++].weight; while( (ht[i].parent != 0) && (i <= j) ) i++; *s2 = i; min2 = ht[i++].weight; if(min1 > min2){ temp = min1; min1 = min2; min2 = temp; } for(; i <= j; i++){ //遍历parent不为0的结点 if(ht[i].parent != 0) continue; if(ht[i].weight <= min1){ min2 = min1; min1 = ht[i].weight; *s2 = *s1; *s1 = i; } else if( (ht[i].weight < min2) && (ht[i].weight > min1) ) { min2 = ht[i].weight; *s2 = i; } } } /*建哈夫曼树*/ void EstHuffmanTree(HuffmanTree ht, int *w, int n){ int i; int s1 = 0, s2 = 0; for(i = 1; i <= n; i++){ //初始化哈夫曼树, 前n个单元存放叶子点 ht[i].weight = w[i]; ht[i].parent = 0; ht[i].Lchild = 0; ht[i].Rchild = 0; } for(i = n+1; i <= 2*n-1; i++){ //后n-1个单元存放非叶子点 ht[i].weight = 0; ht[i].parent = 0; ht[i].Lchild = 0; ht[i].Rchild = 0; } for(i = n+1; i <= 2*n-1; i++){ select_two(ht, i-1, &s1, &s2); //创建非叶子点, 建立哈夫曼树, 每次在ht[1]~ht[i-1]范围内选两个最小的weight结点,并将其序号赋给s1, s2 ht[i].weight = ht[s1].weight + ht[s2].weight; ht[i].Lchild = s1; ht[i].Rchild = s2; ht[s1].parent = i; ht[s2].parent = i; } //哈夫曼树建立完毕 } /*求哈弗曼编码*/ void CrtHuffmanCode(HuffmanTree ht, char **hcd, int n){ int start = 0, c = 0, p = 0, i; char *cd = (char*)malloc(n*sizeof(char)); //分配求当前编码的工作空间 cd[n-1] = '\0'; //从左向右存放编码 for(i = 1; i <= n; i++) { start = n-1; //初始化编码起始指针 c = i; p = ht[i].parent; while(p != 0){ start--; if(ht[p].Lchild == c) cd[start] = '0'; //左分支标0 else cd[start] = '1'; //右分支标1 c = p; //向上倒推 p = ht[c].parent; } hcd[i] = (char*)malloc((n-start)*sizeof(char)); strcpy(hcd[i], &cd[start]); } free(cd); } /*自定义错误处理函数*/ void my_err(char *err_string, int line){ printf("Line %d:\n", line); perror(err_string); exit(1); } /*从 buf_read 中统计每个字符出现的次数,将次数作为该字符的权值*/ void Statistics(difcha a, char *buf_read){ int i, j = 0; for(i = 0; i < strlen(buf_read) ; i++){ //对buf_read中的字符遍历 for(j = 0; j < count; j++){ //检查是否是新的字符 if(a[j].char_date == buf_read[i]){ a[j].num++; //若是旧字符, 则num++; break; } } if(j == count){ //若是新字符, 则记录到a中, 且对应的num++ a[count].char_date = buf_read[i]; a[count].num++; count++; //更新count } } } /*从 SourceDoc.txt 读取数据到 buf_read */ void ReadFile(char *pathName, char *buf_read){ int fd_date; int len = 0; if( (fd_date = open(pathName, O_RDWR)) < 0) //以读写方式打开SourceDoc.txt文件 my_err("open SourceDoc.txt", __LINE__); if(lseek(fd_date, 0, SEEK_END) < 0) //获取文件长度,并保持文件读写指针在文件开始处 my_err("lseek", __LINE__); if( (len = lseek(fd_date, 0, SEEK_CUR)) < 0 ) my_err("lseek", __LINE__); if(lseek(fd_date, 0, SEEK_SET) < 0) my_err("lseek", __LINE__); if(read(fd_date, buf_read, len) > len) //从SourceDoc.txt中读取内容 my_err("read SourceDoc.txt", __LINE__); } /*将 buf_code 写入 Encode.dat 中*/ void WriteFile(char *pathName, char *buf_code){ int fd_code; if((fd_code = open(pathName, O_CREAT|O_TRUNC|O_RDWR, S_IRWXU)) < 0) //创建Encode.dat文件 my_err("open Encode.dat", __LINE__); if( write(fd_code, buf_code, strlen(buf_code)) != strlen(buf_code) ) //将 buf_code 写入Encode.dat my_err("write Encode.dat", __LINE__); } /*主函数*/ void main(){ char buf_read[N] = {'\0'}; char buf_code[N] = {'\0'}; char buf_yima[N] = {'\0'}; char *hcd[N]; char temp[50] = {'\0'}; difcha a; int i, j, n, k = 0, m = 0; int w[N] = {0}; HuffmanTree ht; ReadFile("SourceDoc.txt", buf_read); Statistics(a, buf_read); for(i = 0; i < count; i++) w[i+1] = a[i].num; EstHuffmanTree(ht, w, count); //建HuffmanTree CrtHuffmanCode(ht, hcd, count); //对树中字符进行编码 for(i = 1; i <= count; i++) //将每个字符对应的编码存入结构体 a 中 strcpy(a[i-1].a_code, hcd[i]); FILE *fp1; fp1=fopen("Statistic.txt","w"); for(i = 0; i < count; i++) //查看每个字符的权值和对应的编码 fprintf(fp1,"%c %d %s\n", a[i].char_date, a[i].num, a[i].a_code); fclose(fp1); for(i = 0; i < strlen(buf_read) ; i++){ //遍历 buf_read, 给 SourceDoc.txt 中每个字符匹配编码, 存入 buf_code 中 for(j = 0; j < count; j++){ if(buf_read[i] == a[j].char_date){ strcat(buf_code, a[j].a_code); break; } } if(j == count) //匹配异常 printf("Unknown Character: %c\n", buf_read[i]); } WriteFile("Encode.dat", buf_code); //将 buf_code 写入 Encode.dat 中 ReadFile("Encode.dat", buf_read); //从 Encode.dat 中读取全部编码 n = strlen(buf_read); for(i = 0; i < n; i++){ //为 Encode.dat 中的编码匹配字符 temp[k++] = buf_read[i]; for(j = 0; j < count; j++){ if(strcmp(temp, a[j].a_code) == 0){ buf_yima[m++] = a[j].char_date; break; } } if(j < count){ //匹配成功, 对 temp 初始化 for(;k > 0; k--) temp[k] = '\0'; } } FILE *fp2; fp2=fopen("DecodeDoc.txt","w"); fprintf(fp2,"%s", buf_yima); fclose(fp2); }
C++用哈弗曼编码实现压缩,编码文件比原文件大是怎么回事,怎么能实现压缩,代码如下,求修改
``` #include<iostream> #include<fstream> #include<string> using namespace std; struct HuffmanNode //树结点类定义 { int weight; //权值 int parent; //双亲 int lchild,rchild; //左右孩子 }; class HuffmanTree //哈夫曼树类定义 { private: struct HuffmanNode *Node; //哈夫曼树中结点的存储结构 char *Info; //用来保存各字符信息的字符数组 int LeafNum; //树中的叶子结点总数 public: HuffmanTree(); //构造函数 ~HuffmanTree(); //析构函数 void Initialization(int WeightNum); //初始化函数 void Encoder(); //编码函数,生成哈夫曼编码 void Decoder(); //译码函数,对二进制串进行译码 void Print(); //输出编码 void TreePrinting(); //输出哈夫曼树 }; HuffmanTree::HuffmanTree() //初始化空树 { Node=NULL; //将树结点初始化为空 Info=NULL; //将字符数组初始化为空 LeafNum=0; //将叶子数初始化为0 } HuffmanTree::~HuffmanTree() //析构函数 { delete[] Node; //释放结点空间 delete[] Info; //释放字符存储空间 } //初始化函数 void HuffmanTree::Initialization(int WeightNum) { int i,j,pos1,pos2,max1,max2; Node=new HuffmanNode[2*WeightNum-1]; //为哈夫曼树所需的结点申请空间 Info=new char[2*WeightNum-1]; for(i=0;i<WeightNum;i++) //先构造weightnum个点 { cout<<"请输入第"<<i+1<<"个字符值"; cin>>Info[i]; cout<<"请输入该字符的权值或频度"; cin>>Node[i].weight; //输入权值 Node[i].parent=-1; //为根结点 Node[i].lchild=-1; //无左孩子 Node[i].rchild=-1; //无右孩子 } //这里构造出weightnum个带权结点 for(i=WeightNum;i<2*WeightNum-1;i++) { pos1=-1; pos2=-1; //分别用来存放当前最小值和次小值的所在单元编号 max1=32767; //32767为整型数的最大值 max2=32767; for(j=0;j<i;j++) if(Node[j].parent==-1) if(Node[j].weight<max1) { max2=max1; //原最小值变为次小值 max1=Node[j].weight; //存放最小值 pos2=pos1; //修改次小值所在单元编号 pos1=j; //修改最小值所在单元编号 } else if(Node[j].weight<max2) { max2=Node[j].weight; //存放次小值 pos2=j; //修改次小值所在的单元编号 } Node[pos1].parent=i; //修改父亲位置 Node[pos2].parent=i; Node[i].lchild=pos1; //修改儿子位置 Node[i].rchild=pos2; Node[i].parent=-1; //表示新结点应该是根结点 Node[i].weight=Node[pos1].weight+Node[pos2].weight; } LeafNum=WeightNum; char ch; cout<<"是否要替换原来文件(y/n):"; cin>>ch; if(ch=='y'||ch=='Y') { ofstream fop; //以二进制方式打开hfmTree.dat文件,并当重新运行时覆盖原文件 fop.open("hfmTree.dat",ios::out|ios::binary|ios::trunc); if(fop.fail()) //文件打开失败 cout<<"文件打开失败!\n"; fop.write((char*)&WeightNum,sizeof(WeightNum)); //写入WeightNum for(i=0;i<WeightNum;i++) //把各字符信息写入文件 { fop.write((char*)&Info[i],sizeof(Info[i])); flush(cout); } for(i=0;i<2*WeightNum-1;i++) //把各节点内容写入文件 { fop.write((char*)&Node[i],sizeof(Node[i])); flush(cout); } fop.close(); //关闭文件 } cout<<"哈夫曼树已构造完成。\n"; } //编码函数 void HuffmanTree::Encoder() { if(Node==NULL) { ifstream fip; fip.open("hfmTree.dat",ios::binary|ios::in); //以二进制方式打开hfmTree.dat文件 if(fip.fail()) //文件打开失败 { cout<<"文件打开失败!\n"; return; //结束本函数 } fip.read((char*)&LeafNum,sizeof(LeafNum)); //读取叶子数 Info=new char[LeafNum]; Node=new HuffmanNode[2*LeafNum-1]; for(int i=0;i<LeafNum;i++) //读取字符信息 fip.read((char*)&Info[i],sizeof(Info[i])); for(int i=0;i<2*LeafNum-1;i++) //读取结点信息 fip.read((char*)&Node[i],sizeof(Node[i])); } char *Tree; //用于存储需编码内容 int i=0,num; char Choose; cout<<"从文件中读取内容的请选择1,需要重新输入的请选择2:"; cin>>Choose; if(Choose=='1') //读取文件ToBeTran.txt { ifstream fip1("ToBeTran.txt"); if(fip1.fail()) //文件不存在 { cout<<"文件打开失败!\n"; return; //结束本函数 } char ch; int k=0; while(fip1.get(ch)) { k++; } fip1.close(); Tree=new char[k+1]; ifstream fip2("ToBeTran.txt"); k=0; while(fip2.get(ch)) { Tree[k]=ch; //读取文件内容,并存到Tree中 k++; } fip2.close(); Tree[k]='\0'; //结束标志 cout<<"需编码内容为:"<<Tree<<endl; } //if(Choose=='2') else { string tree; cin.ignore(); cout<<"请输入需要编码的内容(可输入任意长,结束时请按2下回车):\n"; getline(cin,tree,'\n'); //输入任意长字符串, while(tree[i]!='\0') i++; num=i; //计算tree长度 i=0; Tree=new char[num+1]; while(tree[i]!='\0') //将tree中的字符转存到Tree中 { Tree[i]=tree[i]; i++; } Tree[i]='\0'; //结束标志符 } ofstream fop("CodeFile.dat",ios::trunc); i=0; int k=0; char *code; code=new char[LeafNum]; //为所产生编码分配容量为LeafNum的存储空间 while(Tree[k]!='\0') //对每一个字符编码 { int j,start=0; for(i=0;i<LeafNum;i++) if(Info[i]==Tree[k]) break; j=i; while(Node[j].parent!=-1) //结点j非树根 { j=Node[j].parent; //求结点j的双亲结点 if(Node[j].lchild==i) //是左子树,则生成代码0 code[start++]='0'; else code[start++]='1'; //是右子树,则生成代码1 i=j; } code[start]='\0'; //置串结束符 for(i=0;i<start/2;i++) //对二进制序列进行逆置 { j=code[i]; code[i]=code[start-i-1]; code[start-i-1]=j; } i=0; while(code[i]!='\0') //存储代码 { fop<<code[i]; i++; } k++; } fop.close(); cout<<"编码完成!且存到文件CodeFile.dat中!\n\n"; } //解码函数 void HuffmanTree::Decoder() { int i=0,k=0; int j=LeafNum*2-1-1; char* BitStr; ifstream fip1("CodeFile.dat"); //利用已建好的哈夫曼树将文件CodeFile中的代码进行译码 if(fip1.fail()) { cout<< "请先编码!\n"; return; } cout<<"经译码,原内容为:"; char ch; while(fip1.get(ch)) { k++; } fip1.close(); BitStr=new char[k+1]; ifstream fip2("CodeFile.dat"); k=0; while(fip2.get(ch)) { BitStr[k]=ch; //读取文件内容 k++; } fip2.close(); BitStr[k]='\0'; //结束标志符 if(Node==NULL) //还未建哈夫曼树 { cout<<"请先编码!\n"; return; } ofstream fop("TextFile.dat"); //将字符形式的编码文件写入文件CodePrin中 while(BitStr[i]!='\0') { if(BitStr[i]=='0') j=Node[j].lchild; //往左走 else j=Node[j].rchild; //往右走 if(Node[j].rchild==-1) //到达叶子结点 { cout<<Info[j]; //输出叶子结点对应的字符 j=LeafNum*2-1-1; fop<<Info[j]; //存入文件 } i++; } fop.close(); cout<<"\n译码成功且已存到文件TextFile.dat中!\n\n"; } //输出编码函数 void HuffmanTree::Print() { char ch; int i=1; ifstream fip("CodeFile.dat"); ofstream fop("CodePrin.dat"); if(fip.fail()) { cout<<"没有文件,请先编码!\n"; return; } while(fip.get(ch)) { cout<<ch; //读取文件内容 fop<<ch; //存到文件中 if(i==50) { cout<<endl; i=0; } i++; } cout<<endl; fip.close(); //关闭CodeFile.dat文件 fop.close(); //关闭CodePrin.dat文件 } //输出哈夫曼树 void HuffmanTree::TreePrinting() { if(Node==NULL) { cout<<"请先建立哈夫曼树!\n"; return; } ofstream fop("TreePrint.dat"); cout<<"结点位置(权值) "<<"编码 "<<"左孩子 "<<"编码"<<"右孩子('^'表示叶子)\n"; fop<<"结点位置(权值) "<<"编码 "<<"左孩子 "<<"编码"<<"右孩子('^'表示叶子)\n"; int i; for(i=(2*LeafNum-2);i>LeafNum-1;i--) { cout<<i<<"("<<Node[i].weight<<")"<<"--1--" <<Node[i].lchild<<"("<<Node[Node[i].lchild].weight<<")"<<"--0--" <<Node[i].rchild<<"("<<Node[Node[i].rchild].weight<<")"<<endl; fop<<i<<"("<<Node[i].weight<<")"<<"--1--" <<Node[i].lchild<<"("<<Node[Node[i].lchild].weight<<")"<<"--0--" <<Node[i].rchild<<"("<<Node[Node[i].rchild].weight<<")"<<endl; } for(;i>=0;i--) { cout<<i<<":"<<Node[i].weight<<"("<<Info[i]<<")---^\n"; fop<<i<<":"<<Node[i].weight<<"("<<Info[i]<<")---^\n"; } } int main() { cout<<"~~~~~~~~~~~~~welcome to Huffman encodrding&decoding system ~~~~~~~~~~~~~~~~~~~~\n\n"; cout<<"You can choose 1--6 options:\n"; cout<<"(1)初始化 \n"; cout<<"(2) 编码\n"; cout<<"(3) 译码\n"; cout<<"(4) 输出编码\n"; cout<<"(5) 输出哈弗曼树\n"; cout<<"(6) Byebye~!\n\n"; HuffmanTree HT; int weight; int choice; int OK=0; while ( !OK ) { cout<<"Please input your option (1--6):"; cin>> choice; switch( choice) { case 1: cout<<"Please input your code lenth"<<endl; cin>>weight; HT.Initialization(weight); break; case 2: HT.Encoder(); break; case 3: HT.Decoder(); break; case 4: HT.Print();break; case 5: HT.TreePrinting();break; case 6: cout<<"\n***********Thanks for Using!***********\n"; OK=1; break; return 0; } cout<<"(1)初始化\n"; cout<<"(2)编码\n"; cout<<"(3)译码\n"; cout<<"(4)打印哈弗曼编码\n"; cout<<"(5)打印哈弗曼树\n"; cout<<"(6) Byebye~!\n\n"; } return 0; } ```
构建一个哈弗曼树,并计算其带权路径长度
不知道是哪里出现了问题,运行结果不对,并且一点调试就直接结束了,麻烦大神们帮我看一下 ``` # include <stdio.h> static int h = 0; typedef struct tree { char data; int quan; bool min; struct tree* zuo; struct tree* you; }tree; struct hafmman { char data; char lujing[11]; }hafu[100]; void gettree(tree* a,int shij,int youx) { int c = 0; tree temp; if (youx*2-1 != shij) { printf("请输入合法参数"); return; } while (youx!=shij) { for (int i=c;i<shij;++i) { if (a[c].quan>a[i].quan) { temp = a[i]; a[i] = a[c]; a[c] = temp; } if (a[c+1].quan>a[i].quan) { temp = a[i]; a[i] = a[c+1]; a[c+1] = temp; } } a[youx].quan = a[c].quan + a[c+1].quan; a[youx].zuo = &a[c]; a[youx].you = &a[c+1]; youx++; c=c+2; } } int bianltree(tree * tr,char* ch,int deep) { static int i = 0; int j = 0; int sum = 0; if (!tr->min) { ch[i++] = '0'; sum += bianltree(tr->zuo,ch,deep+1); ch[i++] = '1'; sum += bianltree(tr->you,ch,deep+1); } if (tr->min) { ch[i] = '\0'; printf("%c : %s",tr->data,ch); hafu[h].data = tr->data; while (i!=j || i>10) { hafu[h].lujing[j] = ch[j]; j++; } h++; i--; sum = tr->quan * deep; } return sum; } int main () { tree a[9] = {{'a',5,true},{'b',4,true},{'c',2,true},{'d',6,true},{'e',2,true}}; gettree(a,9,5); char ch[100]; int sum = bianltree(&a[8],ch,0); printf("%d",sum); return 0; } ```
哈弗曼编码,从根到叶子,权值从数组为0开始,会出问题,以下代码,知道问题出现在下标为0的权值无法编码
``` while(p1) { if(HT[p1].weight==0) //向左 { HT[p1].weight=1; if(HT[p1].lchild!=0) { p1=HT[p1].lchild; printf("p1为%d \n",p1); cd[cdlen]='0'; cdlen++; } else if(HT[p1].lchild==0&&HT[p1].rchild==0) //登记叶子结点的字符编码 { HC[p1]=(char *)malloc(cdlen*sizeof(char)); cd[cdlen]='\0'; strcpy(HC[p1],cd); //复制编码串 printf("HC的值%s\n",HC[p1]); } } else if(HT[p1].weight==1) //向右 { HT[p1].weight=2; if(HT[p1].rchild!=0) { p1=HT[p1].rchild; cd[cdlen]='1'; cdlen++; } } else //HT[p1].weight==2,退回 { HT[p1].weight=0; p1=HT[p1].parent; --cdlen; //退到父节点,编码长度减1 } } ```
数据结构哈弗曼编码,急急急急急急!
在记事本软件中,放入不小于1000个英文字符的文本,命名为source.txt。 编写过程,挑出文本中的不相同字符,输出文件列出每个字符的出现概率。 根据字符列表文件建立字符列表的哈夫曼编码本1 以哈夫曼编码本1为参照,将文本文件source.txt的内容转换为二进制码文件code.dat 以哈夫曼编码本1为参照,将二进制码文件code1.dat的内容解码为target.txt明文 编写函数,对比source.txt和 target.txt是否相同,不同则返回出现不同的位置点。 大学生的数据结构作业,求大神帮忙啊!
数据结构(C++版)哈弗曼 编码
问题描述:利用哈夫曼编码进行信息通讯可以大大提高信道的利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传输数据预先编码;在接受端将传来的数据进行译码。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站编写一个哈夫曼码编码/译码系统。 基本要求:根据某字符文件统计字符出现频度,构造Huffman 树,编制Huffman编码,并将给定字符文件编码,生成编码文件;再将给定编码文件解码,生成字符文件(要求按二进制位表示编码)。 提高要求:改进Huffman编码,产生两种以上的编码方案,对同一组测试数据,用不同的编码方案编码,并从文件长度、算法复杂度等方面进行比较分析。 测试数据:找一个英文文档文件或中文文档文件。 用C++来编写,能实现基本要求和提高要求的。
代码运行有问题怎么解决
#include <iostream> #include <string> #include <queue> #include <map> using namespace std; /** * @brief 哈弗曼结点 * 记录了哈弗曼树结点的数据、权重及左右儿子 */ struct HTNode { char data; HTNode *lc, *rc; int w; /** 节点构造函数 */ HTNode(char _d, int _w, HTNode *_l = NULL, HTNode *_r = NULL) { data = _d; w = _w; lc = _l; rc = _r; } /** 节点拷贝构造函数 */ HTNode(const HTNode &h) { data = h.data; lc = h.lc; rc = h.rc; w = h.w; } /** 用于优先队列比较的运算符重载 */ friend bool operator < (const HTNode &a, const HTNode &b) { return a.w > b.w; } }; /** 哈弗曼树叶子节点数、各叶子结点数据及权重 */ /** 权值从Lolita小说中抽样取出 */ const char ch[] = { 10, 32, 33, 37, 40, 41, 44, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 63, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 93, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 161, 164, 166, 168, 170, 173, 174, 175, 176, 177, 180, 186, 255, '\r', '\0' }; const int fnum[] = { 2970, 99537, 265, 1, 496, 494, 9032, 1185, 5064, 108, 180, 132, 99, 105, 82, 64, 62, 77, 126, 296, 556, 548, 818, 443, 543, 435, 225, 271, 260, 797, 3487, 158, 50, 1053, 589, 498, 332, 316, 61, 276, 724, 855, 54, 293, 543, 11, 185, 11, 25, 26, 42416, 7856, 12699, 23670, 61127, 10229, 10651, 27912, 32809, 510, 4475, 23812, 13993, 34096, 38387, 9619, 500, 30592, 30504, 42377, 14571, 4790, 11114, 769, 10394, 611, 1, 4397, 12, 71, 117, 1234, 81, 5, 852, 1116, 1109, 1, 3, 1, 2970 }; const int n = 91; /** 优先队列 */ priority_queue<HTNode> pq; /** 哈弗曼编码映射 */ map<string, char> dcode; map<char, string> ecode; /** 根节点以及总权重+边长 */ HTNode *root; int sum = 0; /** 初始化叶节点,并加入到优先队列中 */ void Init() { for(int i = 0; i < n; i++) { HTNode p(ch[i], fnum[i]); pq.push(p); } } /** 建立哈夫曼树 */ void CreateHT() { HTNode *lmin, *rmin; /** 当队列中不止一个元素时 */ while(!pq.empty() && 1 != pq.size()) { /** 取队首两个元素(权值最小) */ lmin = new HTNode(pq.top()); pq.pop(); rmin = new HTNode(pq.top()); pq.pop(); /** 合并元素重新入队 */ HTNode p(0, lmin->w + rmin->w, lmin, rmin); pq.push(p); } if(!pq.empty()) { /** 根节点 */ root = new HTNode(pq.top()); pq.pop(); } } /** 创建哈夫曼编码 */ void CreateHTCode(HTNode *p, string str) { if(!p) return; if(0 != p->data) { /** 若是叶节点,则记录此节点的编码值 */ dcode[str] = p->data; ecode[p->data] = str; sum += (str.length() * p->w); return; } CreateHTCode(p->lc, str + "0"); CreateHTCode(p->rc, str + "1"); } /** 显示哈夫曼编码 */ void DispCode() { printf("输出哈弗曼编码:\n"); for(int i = 0; i < n; i++) { printf("\t'%c':\t%s\n", ch[i], ecode[ch[i]].c_str()); } printf("平均长度:%.5lf\n", double(sum) / double(root->w)); } /** 释放哈夫曼树 */ void Release(HTNode *p) { if(!p) return; Release(p->lc); Release(p->rc); delete p; } /** 输出压缩文 */ void putEncode(FILE *fp, char *buf) { unsigned char code = 0; for(int i = 0; i < 8; i++) code = (code << 1) + (buf[i] - '0'); fwrite(&code, sizeof(unsigned char), 1, fp); } /** 判断是否在字符串内 */ bool instr(char c, const char str[]) { for(int i = 0; i < strlen(str); i++) if(c == str[i]) return true; return false; } /** 压缩文件 */ void Encode() { FILE *OF; FILE *IF; char ifn[255]; const char ofn[] = "Encode.txt"; char buf[9]; int cnt = 0, newcnt = 0; printf("Input the filename: "); scanf("%s", ifn); IF = fopen(ifn, "rb"); if(!IF) { printf("Wrong file.\n"); return; } OF = fopen(ofn, "wb+"); if(!OF) { printf("Wrong file.\n"); } /** 开始读文件 */ memset(buf, 0, sizeof(buf)); while(!feof(IF)) { unsigned char c; fread(&c, sizeof(unsigned char), 1, IF); if(instr(c, ch)); else c = ' '; for(int i = 0; i < ecode[c].length(); i++) { buf[strlen(buf)] = ecode[c][i]; if(8 == strlen(buf)) { newcnt++; putEncode(OF, buf); memset(buf, 0, sizeof(buf)); } } cnt++; } cnt--; if(0 != strlen(buf)) { for(int i = strlen(buf); i < 8; i++) buf[i] = '0'; putEncode(OF, buf); } fwrite(&cnt, 4, 1, OF); fclose(IF); fclose(OF); printf("压缩成功!压缩率:%.2f%c\n", (((double)newcnt + 4.0f) / (double)cnt) * 100, '%'); } /** 补0 */ void putZeros(char *buf) { char tmpbuf[9]; memset(tmpbuf, 0, sizeof(tmpbuf)); if(8 != strlen(buf)) { for(int i = 0; i < 8 - strlen(buf); i++) tmpbuf[i] = '0'; strcat(tmpbuf, buf); strcpy(buf, tmpbuf); } } /** 解压缩 */ void Decode() { char buf[256]; char oldbuf[9]; const char ifn[] = "Encode.txt"; const char ofn[] = "Decode.txt"; FILE *IF = fopen(ifn, "rb"); if(!IF) { printf("Wrong file.\n"); return; } FILE *OF = fopen(ofn, "wb+"); if(!OF) { printf("Wrong file.\n"); return; } int tot, cnt = 0; fseek(IF, -4L, SEEK_END); fread(&tot, 4, 1, IF); fseek(IF, 0L, SEEK_SET); memset(buf, 0, sizeof(buf)); while(true) { if(cnt == tot) break; unsigned char c; fread(&c, sizeof(unsigned char), 1, IF); itoa(c, oldbuf, 2); putZeros(oldbuf); for(int i = 0; i < 8; i++) { if(cnt == tot) break; buf[strlen(buf)] = oldbuf[i]; if(dcode.end() != dcode.find(string(buf))) { fwrite(&dcode[string(buf)], sizeof(char), 1, OF); memset(buf, 0, sizeof(buf)); cnt++; } } } fclose(IF); fclose(OF); printf("解压成功!文件名Decode.txt。\n"); } int main() { Init(); CreateHT(); CreateHTCode(root, ""); DispCode(); Encode(); Decode(); Release(root); system("pause"); return 0; }
下面的这段代码什么意思,帮忙看一下,谢谢!!!
``` void BianMa(MyTreeNode* mtns[]) { MyTreeNode* curr; string codes; char* code = new char[size]; for (int i = 0; i < size; i++) { code[i] = '2'; } for (int i = 0; i < size; i++) { int j = 1; cout<<mtns[i]->data<<"的哈弗曼编码为:"; curr = mtns[i]; while (curr->isfather == true) { curr = curr->father; if (curr->isfather == true){ code[j++] = curr->code; } } code[0] = mtns[i]->code; //cout<<mtns[i]->code<<endl; /*for (int k = j-1; k >= 0; k--) { if (code[k] != '2'){ cout<<code[k]<<" "; } }*/ char c[j]; //cout<<endl<<j<<endl; int count = 0; for (int l = j-1; l >=0; l--) { if (code[l] != '2') { c[count++] = code[l]; //cout<<code[l]<<endl; } } for (int x = 0; x < j; x++) { mtns[i]->codes += c[x]; } cout<<mtns[i]->codes<<endl; cout<<endl; } } ``` 帮忙解释一下这段代码什么意思,请大家帮帮忙,谢谢,感激不尽!!!!
跪求大神 帮忙,这段关于哈夫曼编码 的程序着实看不懂啊。。。。。。。
struct Codetype{//哈弗曼编码数据类型 char *bits;//编码流-数组,n为为哈夫曼树中叶子结点的数目,编码的长度不可能超过n int start;//编码实际在编码流数组里的开始位置 }; Codetype *HuffmanCode(hufmtree *tree){//哈弗曼编码的生成 int i,j,p,k; Codetype *code; if(tree==NULL) return NULL; code=(Codetype*)malloc(tree->n*sizeof(Codetype));//把tree的n个叶子节点生成哈夫曼码 for(i=0;i<tree->n;i++) { printf("%c",tree->node[i].data);//打印字符信息 code[i].bits=(char*)malloc(tree->n*sizeof(char)); code[i].start=tree->n-1; j=i; p=tree->node[i].parent; while(p!=-1){ if(tree->node[p].lchild==j) code[i].bits[code[i].start]='0'; else code[i].bits[code[i].start]='1'; code[i].start--; j=p; p=tree->node[p].parent; } for(k=code[i].start+1;k<tree->n;k++)//打印字符编码 printf("%c",code[i].bits[k]); printf("\n"); } return code; }
学校程序设计实习 刚学了几天MFC 调试的时候出现了错误
![图片说明](https://img-ask.csdn.net/upload/201607/11/1468249717_447162.png) 主要是制作哈弗曼树的窗口 想利用文件在对话框上显示,其它函数里这样用没错,一到这个函数就出错了,而且这个文件只在这个函数中使用了,我是小小白 求大神不吝指教 void printNodeCode(HTNode htnode[], HTCode htcode[], int n) //输出每个结点的编码 { int i,k; int num = 0; FILE *fp = fopen("printNodeCode.txt","w"); for (i = 0; i<=n; i++) { //逐个输出字符对应的哈弗曼编码 // printf("%c:", htnode[i].data); //输出字符 fprintf(fp,"%c:",htnode[i].data);//将编码读入printNodeCode.txt for (k = htcode[i].start; k <= n; k++) { // printf("%c", htcode[i].code[k]); //输出编码 fprintf(fp,"%c",htcode[i].code[k]);//将编码读入printNodeCode.txt } fprintf(fp,"\n");//将编码读入printNodeCode.txt // cout<<endl; } cout<<endl; fclose(fp); }
C/C++ char类型指针数组输入问题
# C/C++ char类型指针数组输入问题 数据结构课程设计,要求从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树并将它存于文件hfmTree中.将已在内存中的哈夫曼树以直观的方式(比如树)显示在终端上。 程序代码如下: ```cpp #include <iostream> #include <string.h> #define N 50 #define M 2*N-1 #define MAX 100 using namespace std; typedef struct { char data[5]; int weight; int parent; int lchild; int rchild; }HTNode; typedef struct { char cd[N]; int start; }HCode; void CreatHT(HTNode ht[], int n) { int i,k,lnode,rnode; int min1,min2; for (i=0; i<2*n-1; i++) { ht[i].parent=ht[i].lchild=ht[i].rchild=-1; } for (i=n; i<2*n-1; i++) { min1=min2=32767; lnode=rnode=-1; for (k=0; k<=i-1; k++) { if (ht[k].parent==-1) { if (ht[k].weight<min1) { min2=min1; rnode=lnode; min1=ht[k].weight; lnode=k; } else if (ht[k].weight<min2) { min2=ht[k].weight; rnode=k; } } } ht[lnode].parent=i; ht[rnode].parent=1; ht[i].weight=ht[lnode].weight+ht[rnode].weight; ht[i].lchild=lnode; ht[i].rchild=rnode; } } void CreatHCode(HTNode ht[], HCode hcd[], int n) { int i,f,c; HCode hc; for (i=0; i<n; i++) { hc.start=n; c=i; f=ht[i].parent; while (f!=-1) { if (ht[f].lchild==c) { hc.cd[hc.start--]='0'; } else { hc.cd[hc.start--]='1'; } c=f; f=ht[f].parent; } hc.start++; hcd[i]=hc; } } void DispHCode(HTNode ht[], HCode hcd[], int n) { int i,k; int sum=0,m=0,j; printf("输出哈弗曼编码:\n"); for (i=0; i<n; i++) { j=0; printf(" %s:\t", ht[i].data); for (k=hcd[i].start; k<=n; k++) { printf("%c", hcd[i].cd[k]); j++; } m+=ht[i].weight; sum+=ht[i].weight*j; } printf("\n平均长度=%g\n", 1.0*sum/m); } int main(int argc, const char * argv[]) { // insert code here... int n,i; char *str[MAX];//这里定义了一个指针数组存放哈夫曼编码 int fnum[MAX]; HTNode ht[M]; HCode hcd[N]; printf("输如字符集大小:"); scanf("%d", &n); printf("输入%d个字符:", n); for (i=0; i<n; i++) { scanf("%s", str[i]);//这里的输入应该如何修改? } printf("输入%d个权值:", n); for (i=0; i<n; i++) { scanf("%d", &fnum[i]); } for (i=0; i<n; i++) { strcpy(ht[i].data, str[i]); ht[i].weight=fnum[i]; } CreatHT(ht, n); CreatHCode(ht, hcd, n); DispHCode(ht, hcd, n); return 1; } ``` 有问题的地方已在主函数中注释,其他的函数都是哈夫曼树的基本算法。 困扰许久求大佬解决!
下面的错误怎么改啊,请大家帮帮我,我刚开始写,写不好啊。耐心看一下,谢谢!!
``` #include <iostream> #include <string> #define MAX 100 using namespace std; class HTNode { public: int weight; string data; int f; HTNode* father; HTNode* lchild; HTNode* rchild; string code; HTNode() { weight=0; data='0'; code='0'; f=0; father=NULL; lchild=NULL; rchild=NULL; } void SetChild (HTNode* lchild, HTNode* rchild) { this->lchild = lchild; this->rchild = rchild; } void SetF(int f) { this->f = f; } void SetFather(HTNode* father) { this->father = father; } }; void SelectMin(HTNode*ht[], int*a1,int*a2) { int min1=0; int min2=0; for(int i=0;i<2*MAX-1;i++) { if(ht[min1]->weight>ht[i]->weight) min1=i; } min2=min1+1; for(int i=0;i<2*MAX-1;i++) { if(ht[min2]->weight>ht[i]->weight) min2=i; } *a1=min1; *a2=min2; } void Printtree(HTNode* root, int n) { if (root==NULL) return; for (int i=0;i<n;i++) { cout<<" "; } if (root->f==1) { cout<<"|_"; } else { cout<<" "; } cout<<root->data<<endl; Printtree(root->lchild, n+2); Printtree(root->rchild, n+2); } void Bianma(HTNode*ht[]) { HTNode* curr; string* code = new string[MAX]; for (int i = 0; i < MAX ; i++) { code[i] = '2'; } for (int i = 0; i < MAX; i++) { int j = 1; cout<<ht[i]->data<<"的哈弗曼编码为:"; curr = ht[i]; while (curr->f==1) { curr=curr->father; if (curr->f==1){ code[j++]=curr->code; } } code[0] = ht[i]->code; string c[j]; int count = 0; for (int l = j-1; l >=0; l--) { if (code[l]!= '2') { c[count++] = code[l]; } } for (int x = 0; x < j; x++) { ht[i]->code += c[x]; } cout<<ht[i]->code<<endl; cout<<endl; } } void FanYi(HTNode* ht[]) { string code; string test = ""; HTNode* curr; HTNode* root; cout<<"请输入编码:"<<endl; cin>>code; int n = code.length(); string* cs = new string[n]; code.copy(cs, n, 0); for (int i = 0; i < MAX*2-1; i++) { if (ht[i]->f == 0) { root = ht[i]; } } curr = root; for (int i = 0; i < n; i++) { if (cs[i] == '0' && curr->lchild != NULL) { curr = curr->lchild; test += '0'; } else if (cs[i] == '1') { curr = curr->rchild; test += '1'; } if (curr->lchild == NULL || curr->rchild == NULL) { curr = root; for (int i = 0; i < MAX; i++) { if (ht[i]->code == test) { cout<<ht[i]->data; test = ""; } } } } cout<<endl; } void GouJian(string* s, int* n) { int a1, a2, m; m = 2*MAX-1; HTNode* ht[2*MAX-1]; for (int i=0;i<MAX;i++) { ht[i] = new HTNode(s[i], n[i]); } for (int i=MAX;i<2*MAX-1;i++) { ht[i] = new HTNode('0'); } for (int i = 0; i < MAX-1; i++) { SelectMin(ht, &a1, &a2); ht[MAX+i]->weight = ht[a1]->weight + ht[a2]->weight; if (ht[a1]->weight <= ht[a2]->weight) { ht[MAX+i]->SetChild(ht[a1], ht[a2]); ht[a1]->code = '0'; ht[a2]->code = '1'; } else { ht[MAX+i]->SetChild(ht[a2], ht[a1]); ht[a1]->code = '1'; ht[a2]->code = '0'; } ht[a1]->SetF(1); ht[a2]->SetF(1); ht[a1]->SetFather(ht[MAX+i]); ht[a2]->SetFather(ht[MAX+i]); for (int i=0;i<2*MAX-1;i++) { cout<<ht[i]->weight<<" "; } cout<<endl; } cout<<"您输入的哈夫曼树为:"<<endl<<endl; for (int i = 0;i<2*MAX-1;i++) { if (ht[i]->father == 0) { Printtree(ht[i], MAX); cout<<endl; } } cout<<"根据系统分析,有以下结论:"<<endl; Bianma(ht); cout<<endl; FanYi(ht); } ``` 错误信息 error: no matching function for call to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::copy(std::string*&, int&, int)' error: no match for 'operator!=' in '*((+(((unsigned int)l) * 4u)) + code) != '2' error: no matching function for call to `HTNode::HTNode(char)'
130 个相见恨晚的超实用网站,一次性分享出来
文末没有公众号,只求 点赞 + 关注 搞学习 知乎:www.zhihu.com 大学资源网:http://www.dxzy163.com/ 简答题:http://www.jiandati.com/ 网易公开课:https://open.163.com/ted/ 网易云课堂:https://study.163.com/ 中国大学MOOC:www.icourse163.org 网易云课堂:stu
终于明白阿里百度这样的大公司,为什么面试经常拿ThreadLocal考验求职者了
点击上面↑「爱开发」关注我们每晚10点,捕获技术思考和创业资源洞察什么是ThreadLocalThreadLocal是一个本地线程副本变量工具类,各个线程都拥有一份线程私有的数
win10系统安装教程(U盘PE+UEFI安装)
一、准备工作 u盘,电脑一台,win10原版镜像(msdn官网) 二、下载wepe工具箱  极力推荐微pe(微pe官方下载) 下载64位的win10 pe,使用工具箱制作启动U盘打开软件,   选择安装到U盘(按照操作无需更改) 三、重启进入pe系统   1、关机后,将U盘插入电脑 2、按下电源后,按住F12进入启动项选择(技嘉主板是F12)     选择需要启
程序员必须掌握的核心算法有哪些?
由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我,数据结构与算法应该要学习到哪个程度呢?,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,我稍微总结一下我学过的算法知识点,以及我觉得值得学习的算法。这些算法与数据结构的学习大多数是零散的,并没有一本把他们全部覆盖的书籍。下面是我觉得值得学习的一些算法以及数据结构,当然,我也会整理一些看过
大学四年自学走来,这些私藏的实用工具/学习网站我贡献出来了
大学四年,看课本是不可能一直看课本的了,对于学习,特别是自学,善于搜索网上的一些资源来辅助,还是非常有必要的,下面我就把这几年私藏的各种资源,网站贡献出来给你们。主要有:电子书搜索、实用工具、在线视频学习网站、非视频学习网站、软件下载、面试/求职必备网站。 注意:文中提到的所有资源,文末我都给你整理好了,你们只管拿去,如果觉得不错,转发、分享就是最大的支持了。 一、PDF搜索网站推荐 对于大部
C语言魔塔游戏
很早就很想写这个,今天终于写完了。 游戏截图: 编译环境: VS2017 游戏需要一些图片,如果有想要的或者对游戏有什么看法的可以加我的QQ 2985486630 讨论,如果暂时没有回应,可以在博客下方留言,到时候我会看到。 下面我来介绍一下游戏的主要功能和实现方式 首先是玩家的定义,使用结构体,这个名字是可以自己改变的 struct gamerole { char n
java源码分析 Arrays.asList()与Collections.unmodifiableList()
举个栗子 本章示例代码来自java编程思想——17.4.1未获支持的操作——Unsupported类。 import java.util.*; public class Unsupported { static void test(String msg, List&lt;String&gt; list) { System.out.println("--- " + msg
究竟你适不适合买Mac?
我清晰的记得,刚买的macbook pro回到家,开机后第一件事情,就是上了淘宝网,花了500元钱,找了一个上门维修电脑的师傅,上门给我装了一个windows系统。。。。。。 表砍我。。。 当时买mac的初衷,只是想要个固态硬盘的笔记本,用来运行一些复杂的扑克软件。而看了当时所有的SSD笔记本后,最终决定,还是买个好(xiong)看(da)的。 已经有好几个朋友问我mba怎么样了,所以今天尽量客观
Python爬虫爬取淘宝,京东商品信息
小编是一个理科生,不善长说一些废话。简单介绍下原理然后直接上代码。 使用的工具(Python+pycharm2019.3+selenium+xpath+chromedriver)其中要使用pycharm也可以私聊我selenium是一个框架可以通过pip下载 pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple/ 
Java学习笔记(七十二)—— Cookie
概述 会话技术: 会话:一次会话中包含多次请求和响应 一次会话:浏览器第一次给服务器发送资源请求,会话建立,直到有一方断开为止 功能:在一次会话的范围内的多次请求间,共享数据 方式: 客户端会话技术:Cookie,把数据存储到客户端 服务器端会话技术:Session,把数据存储到服务器端 Cookie 概念:客户端会话技术,将数据存储到客户端 快速入门: 使用步骤: 创建C
程序员写了一个新手都写不出的低级bug,被骂惨了。
你知道的越多,你不知道的越多 点赞再看,养成习惯 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试点思维导图,也整理了很多我的文档,欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西。 前前言 为啥今天有个前前言呢? 因为你们的丙丙啊,昨天有牌面了哟,直接被微信官方推荐,知乎推荐,也就仅仅是还行吧(心里乐开花)
Java工作4年来应聘要16K最后没要,细节如下。。。
前奏: 今天2B哥和大家分享一位前几天面试的一位应聘者,工作4年26岁,统招本科。 以下就是他的简历和面试情况。 基本情况: 专业技能: 1、&nbsp;熟悉Sping了解SpringMVC、SpringBoot、Mybatis等框架、了解SpringCloud微服务 2、&nbsp;熟悉常用项目管理工具:SVN、GIT、MAVEN、Jenkins 3、&nbsp;熟悉Nginx、tomca
2020年,冯唐49岁:我给20、30岁IT职场年轻人的建议
点击“技术领导力”关注∆  每天早上8:30推送 作者| Mr.K   编辑| Emma 来源| 技术领导力(ID:jishulingdaoli) 前天的推文《冯唐:职场人35岁以后,方法论比经验重要》,收到了不少读者的反馈,觉得挺受启发。其实,冯唐写了不少关于职场方面的文章,都挺不错的。可惜大家只记住了“春风十里不如你”、“如何避免成为油腻腻的中年人”等不那么正经的文章。 本文整理了冯
程序员该看的几部电影
##1、骇客帝国(1999) 概念:在线/离线,递归,循环,矩阵等 剧情简介: 不久的将来,网络黑客尼奥对这个看似正常的现实世界产生了怀疑。 他结识了黑客崔妮蒂,并见到了黑客组织的首领墨菲斯。 墨菲斯告诉他,现实世界其实是由一个名叫“母体”的计算机人工智能系统控制,人们就像他们饲养的动物,没有自由和思想,而尼奥就是能够拯救人类的救世主。 可是,救赎之路从来都不会一帆风顺,到底哪里才是真实的世界?
蓝桥杯知识点汇总:基础知识和常用算法
文章目录JAVA基础语法:算法竞赛常用的JAVA API:基础算法待更: 此系列包含蓝桥杯所考察的绝大部分知识点,一共有基础语法,常用API,基础算法和数据结构,和往年真题四部分,虽然语言以JAVA为主,但算法部分是相通的,C++组的小伙伴也可以看哦。所有文章的链接都会在此公布,还有很多没有更新,会持续更新,如果大佬发现文章有错误的地方请指正,我会十分感谢。另外,有什么问题可私信我~ JAVA基础
作为一个程序员,CPU的这些硬核知识你必须会!
CPU对每个程序员来说,是个既熟悉又陌生的东西? 如果你只知道CPU是中央处理器的话,那可能对你并没有什么用,那么作为程序员的我们,必须要搞懂的就是CPU这家伙是如何运行的,尤其要搞懂它里面的寄存器是怎么一回事,因为这将让你从底层明白程序的运行机制。 随我一起,来好好认识下CPU这货吧 把CPU掰开来看 对于CPU来说,我们首先就要搞明白它是怎么回事,也就是它的内部构造,当然,CPU那么牛的一个东
破14亿,Python分析我国存在哪些人口危机!
2020年1月17日,国家统计局发布了2019年国民经济报告,报告中指出我国人口突破14亿。 猪哥的朋友圈被14亿人口刷屏,但是很多人并没有看到我国复杂的人口问题:老龄化、男女比例失衡、生育率下降、人口红利下降等。 今天我们就来分析一下我们国家的人口数据吧! 一、背景 1.人口突破14亿 2020年1月17日,国家统计局发布了 2019年国民经济报告 ,报告中指出:年末中国大陆总人口(包括31个
实现简单的轮播图(单张图片、多张图片)
前言 刚学js没多久,这篇博客就当做记录了,以后还会完善的,希望大佬们多多指点。ps:下面出现的都是直接闪动,没有滑动效果的轮播图。 单张图片的替换 原理 1.将几张图片叠在一起,通过改变"display:block"和"display:none"这两个属性实现替换。 (前提:在css中给所有图片加上display:none属性) 2.不用将图片叠在一起,将一个div当做"窗口",通过"of
强烈推荐10本程序员在家读的书
很遗憾,这个鼠年春节注定是刻骨铭心的,新型冠状病毒让每个人的神经都是紧绷的。那些处在武汉的白衣天使们,尤其值得我们的尊敬。而我们这些窝在家里的程序员,能不外出就不外出,就是对社会做出的最大的贡献。 有些读者私下问我,窝了几天,有点颓丧,能否推荐几本书在家里看看。我花了一天的时间,挑选了 10 本我最喜欢的书,你可以挑选感兴趣的来读一读。读书不仅可以平复恐惧的压力,还可以对未来充满希望,毕竟苦难终
Linux自学篇——linux命令英文全称及解释
man: Manual 意思是手册,可以用这个命令查询其他命令的用法。 pwd:Print working directory 显示当前目录 su:Swith user 切换用户,切换到root用户 cd:Change directory 切换目录 ls:List files 列出目录下的文件 ps:Process Status 进程状态 mk
Python实战:抓肺炎疫情实时数据,画2019-nCoV疫情地图
文章目录1. 前言2. 数据下载3. 数据处理4. 数据可视化 1. 前言 今天,群里白垩老师问如何用python画武汉肺炎疫情地图。白垩老师是研究海洋生态与地球生物的学者,国家重点实验室成员,于不惑之年学习python,实为我等学习楷模。先前我并没有关注武汉肺炎的具体数据,也没有画过类似的数据分布图。于是就拿了两个小时,专门研究了一下,遂成此文。 2月6日追记:本文发布后,腾讯的数据源多次变更u
智力题(程序员面试经典)
NO.1  有20瓶药丸,其中19瓶装有1克/粒的药丸,余下一瓶装有1.1克/粒的药丸。给你一台称重精准的天平,怎么找出比较重的那瓶药丸?天平只能用一次。 解法 有时候,严格的限制条件有可能反倒是解题的线索。在这个问题中,限制条件是天平只能用一次。 因为天平只能用一次,我们也得以知道一个有趣的事实:一次必须同时称很多药丸,其实更准确地说,是必须从19瓶拿出药丸进行称重。否则,如果跳过两瓶或更多瓶药
Java与Python学习通法(1)和(2)序言和编程语言发展史怎么学
大家好,我是 jacky 朱元禄,很高兴跟大家一起学习 《Java与Python学习通法系列》。 首先,说一下,我为什么要录这个课; 我们都已经知道Java 和 Python的视频教程和书籍,可以说是非常非常多了,那我录制本系列课的意义是什么呢? (1)课程特色一:我想告诉大家学习编程语言是有捷径的,这个捷径就是 理解技术背后的“哲学逻辑”,或者说是“人文逻辑”,相信你听完 jack
在家远程办公效率低?那你一定要收好这个「在家办公」神器!
相信大家都已经收到国务院延长春节假期的消息,接下来,在家远程办公可能将会持续一段时间。 但是问题来了。远程办公不是人在电脑前就当坐班了,相反,对于沟通效率,文件协作,以及信息安全都有着极高的要求。有着非常多的挑战,比如: 1在异地互相不见面的会议上,如何提高沟通效率? 2文件之间的来往反馈如何做到及时性?如何保证信息安全? 3如何规划安排每天工作,以及如何进行成果验收? ......
作为一个程序员,内存和磁盘的这些事情,你不得不知道啊!!!
截止目前,我已经分享了如下几篇文章: 一个程序在计算机中是如何运行的?超级干货!!! 作为一个程序员,CPU的这些硬核知识你必须会! 作为一个程序员,内存的这些硬核知识你必须懂! 这些知识可以说是我们之前都不太重视的基础知识,可能大家在上大学的时候都学习过了,但是嘞,当时由于老师讲解的没那么有趣,又加上这些知识本身就比较枯燥,所以嘞,大家当初几乎等于没学。 再说啦,学习这些,也看不出来有什么用啊!
阿里架构师花近十年时间整理出来的Java核心知识pdf(Java岗)
由于细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容! 整理了一份Java核心知识点。覆盖了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。       欢迎大家加入java学习交流社区  点击加入   可获取文中文档       小编推荐:     
Python基础知识点梳理
python基础知识点梳理 摘要: 本文主要介绍一些平时经常会用到的python基础知识点,用于加深印象,也算是对于学习这门语言的一个总结与回顾。python的详细语法介绍可以查看官方编程手册,也有一些在线网站对python语法进行了比较全面的介绍,比如菜鸟教程: python3 教程|菜鸟教程 为了方便聚焦知识点,本文涉及的操作实例并不多,想学好一门语言关键还得自己多编码多实践。 python语
2020年2月全国程序员工资统计,平均工资13716元
趋势 2020年2月,中国大陆程序员平均工资13716元,比上个月增加。具体趋势如图: 各主要程序员城市工资变化 城市 北京,上海,深圳,杭州,广州四地的工资最高。 city 平均工资 最低工资 中位数 最高工资 招聘人数 百分比 北京 18098 3750 15000 45000 20529 9.53% 深圳 16903 5750 15000 37500 30941 14
Java坑人面试题系列: 包装类(中级难度)
Java Magazine上面有一个专门坑人的面试题系列: https://blogs.oracle.com/javamagazine/quiz-2。 这些问题的设计宗旨,主要是测试面试者对Java语言的了解程度,而不是为了用弯弯绕绕的手段把面试者搞蒙。 如果你看过往期的问题,就会发现每一个都不简单。 这些试题模拟了认证考试中的一些难题。 而 “中级(intermediate)” 和 “高级(ad
为什么说程序员做外包没前途?
之前做过不到3个月的外包,2020的第一天就被释放了,2019年还剩1天,我从外包公司离职了。我就谈谈我个人的看法吧。首先我们定义一下什么是有前途 稳定的工作环境 不错的收入 能够在项目中不断提升自己的技能(ps:非技术上的认知也算) 找下家的时候能找到一份工资更高的工作 如果你目前还年轻,但高不成低不就,只有外包offer,那请往下看。 外包公司你应该
基于Python的人脸自动戴口罩系统
目录 1、项目背景 2、页面设计 3、器官识别 4、退出系统 1、项目背景 2019年新型冠状病毒感染的肺炎疫情发生以来,牵动人心,举国哀痛,口罩、酒精、消毒液奇货可居。 抢不到口罩,怎么办?作为技术人今天分享如何使用Python实现自动戴口罩系统,来安慰自己,系统效果如下所示: 本系统的实现原理是借助 Dlib模块的Landmark人脸68个关键点检测库轻松识别出人脸五官
相关热词 c#开发的dll注册 c#的反射 c# grid绑定数据源 c#多线程怎么循环 c# 鼠标左键 c# char占位符 c# 日期比较 c#16进制转换为int c#用递归求顺序表中最大 c#小型erp源代码
立即提问