比赛描述
输入
输出
共十行:
前八行为各字符的编码;
第九行是与第二行输入对应的哈夫曼编码;
第十行是与第三行输入对应的电文。
样例输入
1 2 3 4 5 6 7 8
NUPTICPCACM
1111011111100
样例输出
A: 11110
C: 11111
I: 1110
M: 100
N: 101
P: 110
T: 00
U: 01
1010111000111011111110111111111011111100
ACM
提示
2012.4.11 更新
题目来源
NUPT ACM
#include <iostream> #include <cassert> #include <string> #define MAX(a,b) (a>b?a:b) using namespace std; template<typename Type> class QueueNode{ public: Type data; QueueNode *next; }; template<typename Type> class Queue{ public: QueueNode<Type> *Head; //指向第一个元素,方便出队 QueueNode<Type> *Tail; //指向最后一个元素,方便插入 void PushBack(const Type&); Type PopFront(void); }; /* *函数功能:队尾加入新元素 *入口参数:const Type& data:将要插入的元素 *出口参数:无 *作者:陈汝军 *时间:2014-8-19 20:17:13 */ template<typename Type> void Queue<Type>::PushBack(const Type& data){ if(Head == NULL){ Head = new QueueNode<Type>(); Head->data = data; Tail = Head; }else{ Tail->next = new QueueNode<Type>(); Tail->next->data = data; Tail = Tail->next; } } /* *函数功能:队首弹出元素 *入口参数:无 *出口参数:Type PopFront:弹出的元素 *作者:陈汝军 *时间:2014-8-19 20:18:08 */ template<typename Type> Type Queue<Type>::PopFront(void){ QueueNode<Type> *TempHead = Head; Type TempData = Head->data; assert(Head!=NULL); Head = Head->next; delete TempHead; return TempData; } template<typename Type> class BTNode{ public: Type data; BTNode *lChild; BTNode *rChild; BTNode *parent; void PreOrder(void); void InOrder(void); void PostOrder(void); static void PreOrderInput(BTNode<Type>* &Head); //静态成员函数,调用与具体的类无关 int Height(void); int NodeNum(void); int LeafNum(void); void TransLevel(void); void Exchange(void); }; /* *函数功能:先序遍历二叉树。 *入口参数:this. *出口参数:无 *作者:陈汝军 *时间:2014-8-18 22:01:59 */ template<typename Type> void BTNode<Type>::PreOrder(){ if(this == NULL) return; cout<<" "<<this->data; this->lChild->PreOrder(); this->rChild->PreOrder(); } /* *函数功能:中序遍历二叉树。 *入口参数:this. *出口参数:无 *作者:陈汝军 *时间:2014-8-18 22:03:36 */ template<typename Type> void BTNode<Type>::InOrder(){ if(this == NULL) return; this->lChild->InOrder(); cout<<" "<<this->data; this->rChild->InOrder(); } /* *函数功能:后序遍历二叉树。 *入口参数:this. *出口参数:无 *作者:陈汝军 *时间:2014-8-18 22:04:09 */ template<typename Type> void BTNode<Type>::PostOrder(){ if(this == NULL) return; this->lChild->PostOrder(); this->rChild->PostOrder(); cout<<" "<<this->data; } /* *函数功能:先序输入二叉树,用#代表空树或空子树。 *入口参数:BTNode* &Head:树的节点指针的引用 *出口参数:无 *作者:陈汝军 *时间:2014-8-18 22:01:59 */ template<typename Type> void BTNode<Type>::PreOrderInput(BTNode* &Head){ Type data; cin>>data; if(data == '#'){ Head = NULL; }else{ Head = new BTNode<Type>(); Head->data = data; BTNode<char>::PreOrderInput(Head->lChild); BTNode<char>::PreOrderInput(Head->rChild); } } /* *函数功能:输出二叉树的高度 *入口参数:this:本节点指针 *出口参数:Height:高度 *作者:陈汝军 *时间:2014-8-19 10:21:03 */ template<typename Type> int BTNode<Type>::Height(void){ if(this == NULL){ return 0; }else{ return MAX(this->lChild->Height(),this->rChild->Height())+1; } } /* *函数功能:求二叉树的总结点数 *入口参数:this:本节点指针 *出口参数:NodeNum:以本节点为树根的总节点数 *作者:陈汝军 *时间:2014-8-19 10:24:16 */ template<typename Type> int BTNode<Type>::NodeNum(void){ if(this == NULL){ return 0; }else{ return this->lChild->NodeNum()+this->rChild->NodeNum()+1; } } /* *函数功能:求二叉树的叶节点数 *入口参数:this:本节点指针 *出口参数:LeafNum:以本节点为树根的叶节点数 *作者:陈汝军 *时间:2014-8-19 10:29:36 */ template<typename Type> int BTNode<Type>::LeafNum(void){ if(this==NULL){ return 0; }else if(this->lChild==NULL && this->rChild==NULL){ return 1; }else{ return this->lChild->LeafNum()+this->rChild->LeafNum(); } } /* *函数功能:层次遍历二叉树 *入口参数:无 *出口参数:无 *作者:陈汝军 *时间:2014-8-19 20:48:29 */ template<typename Type> void BTNode<Type>::TransLevel(void){ Queue<BTNode<Type>*> *que = new Queue<BTNode<Type>*>(); if(this == NULL) return; que->PushBack(this); while(que->Head!=NULL){ //输出整个队列,输出过程中队列在增长 if(que->Head->data->lChild!=NULL){ que->PushBack(que->Head->data->lChild); } if(que->Head->data->rChild!=NULL){ que->PushBack(que->Head->data->rChild); } cout<<" "<<que->PopFront()->data; } } /* *函数功能:二叉树上所有左右子树互换 *入口参数:无 *出口参数:无 *作者:陈汝军 *时间:2014-8-20 19:20:40 */ template<typename Type> void BTNode<Type>::Exchange(void){ BTNode<Type> *Temp; if(this == NULL){ return; } if(this->lChild!=NULL || this->rChild!=NULL){ Temp = this->lChild; this->lChild = this->rChild; this->rChild = Temp; } this->lChild->Exchange(); this->rChild->Exchange(); } ///////////////////////////////////////////////////////////////////////上面是通用模板 class HufCode{ public: char ch; int weight; }; typedef BTNode<HufCode> HufTree; class HufLink{ public: HufTree *hTree; HufLink *next; void InsertAndSort(char newchar,int newweight); void InsertAndSort(HufLink *newLink); void outputList(void); }; ostream& operator<<(ostream &out,const HufCode &hCode) //我是输出操作符的重载 { out<<hCode.weight<<" "<<hCode.ch<<endl; return out; } /* *函数功能:往HufLink中插入一个新元素。 *入口参数:char newchar:新元素的ch值 int newweight:新元素的weight值 *出口参数:无 *作者:陈汝军 *时间:2014-8-21 09:06:14 */ void HufLink::InsertAndSort(char newchar,int newweight){ HufLink *p=this; HufLink *q=new HufLink(); q->hTree = new HufTree(); q->hTree->data.ch = newchar; q->hTree->data.weight = newweight; if(p->next == NULL){ //链表中一个元素也没有 p->next = q; return; } while(p->next!=NULL && p->next->hTree->data.weight<newweight){ p = p->next; } q->next = p->next; p->next = q; } /* *函数功能:往HufLink中插入一个已经存在的新元素。 *入口参数:HufLink *newLink:指向新元素的指针 *出口参数:无 *作者:陈汝军 *时间:2014-8-21 09:07:00 */ void HufLink::InsertAndSort(HufLink *newLink){ HufLink *p=this; if(p->next == NULL){ //链表中一个元素也没有 p->next = newLink; return; } while(p->next!=NULL && p->next->hTree->data.weight<newLink->hTree->data.weight){ p = p->next; } newLink->next = p->next; p->next = newLink; } /* *函数功能:从头到尾输出Huffman链表 *入口参数:无 *出口参数:无 *作者:陈汝军 *时间:2014-8-20 20:01:45 */ void HufLink::outputList(void){ HufLink *p=this->next; //头指针没有元素 while(p!=NULL){ cout<<p->hTree->data.ch<<":"<<p->hTree->data.weight<<endl; p = p->next; } } /*HufLink里面存放*HufCode是建立不好树的,HufLink中应该存放HufTree*/ HufTree* makeHufTree(HufLink* hLink){ HufLink *p,*q,*newNode; if(hLink==NULL || hLink->next==NULL){ //HufLink头指针不存放元素 return NULL; } while(hLink->next->next!=NULL){ newNode = new HufLink(); newNode->hTree = new HufTree(); p = hLink->next; q = hLink->next->next; newNode->hTree->data.weight = p->hTree->data.weight+q->hTree->data.weight; if(p->hTree->data.weight<q->hTree->data.weight){ newNode->hTree->lChild = p->hTree; //左小右大 newNode->hTree->rChild = q->hTree; p->hTree->parent = newNode->hTree; q->hTree->parent = newNode->hTree; }else{ newNode->hTree->lChild = q->hTree; //左小右大 newNode->hTree->rChild = p->hTree; p->hTree->parent = newNode->hTree; q->hTree->parent = newNode->hTree; } hLink = hLink->next->next; hLink->InsertAndSort(newNode); } return hLink->next->hTree; } class CodeLink{ //头指针不放元素 public: bool codebit; CodeLink *next; void addBit(bool bit); void reverse(void); }; void CodeLink::addBit(bool bit){ CodeLink *p=this,*q=new CodeLink(); q->codebit = bit; if(p->next ==NULL){ p->next = q; return; } while(p->next!=NULL){ p = p->next; } p->next = q; } void CodeLink::reverse(void){ CodeLink *p=this->next,*q=NULL; if(p == NULL){ return; } while(p->next!=NULL){ q = p->next; p->next = q->next; q->next = this->next; this->next = q; } } CodeLink* cLink[256]={NULL}; //所有ASCII码到Huffman码转换 void cLinks(HufTree* hTree){ HufTree *p=hTree; if(hTree == NULL) return; if(p->lChild==NULL && p->rChild==NULL){ //是叶节点 cLink[hTree->data.ch] = new CodeLink(); while(p->parent!=NULL){ if(p->parent->lChild == p){ cLink[hTree->data.ch]->addBit(0); //做孩子0 }else{ cLink[hTree->data.ch]->addBit(1); //右孩子1 } p = p->parent; } cLink[hTree->data.ch]->reverse(); } cLinks(hTree->lChild); cLinks(hTree->rChild); } void printHufCode(char ch){ CodeLink *p=cLink[ch]->next; while(p!=NULL){ cout<<p->codebit; p = p->next; } } int main(void){ int weight[256]={0},i=0; string str,num; HufLink *hLink = new HufLink(); cin>>weight['A']>>weight['C']>>weight['I']>>weight['M']>>weight['N']>>weight['P']>>weight['T']>>weight['U']; cin>>str>>num; hLink->InsertAndSort('A',weight['A']); hLink->InsertAndSort('C',weight['C']); hLink->InsertAndSort('I',weight['I']); hLink->InsertAndSort('M',weight['M']); hLink->InsertAndSort('N',weight['N']); hLink->InsertAndSort('P',weight['P']); hLink->InsertAndSort('T',weight['T']); hLink->InsertAndSort('U',weight['U']); // hLink->outputList(); HufTree *hTree = makeHufTree(hLink),*p=NULL; // hTree->PreOrder(); cLinks(hTree); cout<<"A: ";printHufCode('A');cout<<endl; cout<<"C: ";printHufCode('C');cout<<endl; cout<<"I: ";printHufCode('I');cout<<endl; cout<<"M: ";printHufCode('M');cout<<endl; cout<<"N: ";printHufCode('N');cout<<endl; cout<<"P: ";printHufCode('P');cout<<endl; cout<<"T: ";printHufCode('T');cout<<endl; cout<<"U: ";printHufCode('U');cout<<endl; while(str[i]!='\0'){ printHufCode(str[i]); ++i; } cout<<endl; p = hTree; i = 0; while(num[i]!='\0'){ if(num[i] == '0'){ p = p->lChild; }else{ p = p->rChild; } if(p->lChild==NULL && p->rChild==NULL){ //叶节点 cout<<p->data.ch; p = hTree; } ++i; } cout<<endl; return 0; }