버프맨 트리와 버프맨 인코딩
직접 부호:
#include <iostream>
#include <cstdarg>
using namespace std;
class Node{
public:
int weight;
int parent, lChildren, rChildren;
Node(int weight, int parent, int lChildren, int rChildren):
weight(weight), parent(parent), lChildren(lChildren), rChildren(rChildren)
{
}
void printNode(){
cout<<"weight = "<<weight<<", ";
cout<<"parent = "<<parent<<", ";
cout<<"lChildren = "<<lChildren<<", ";
cout<<"rChildren = "<<rChildren<<endl;
}
};
class Tree{
Node **nodes;
char** huffmanCodec;
int length,rPos;
int mNum;
/** Tree Node。
*
**/
void addNode(Node *node){
if(!node){
cout<<"addNode , NULL"<<endl;
return;
}
for(int i = 0; i < length; i++){
if(node == nodes[i])// 。。
return;
}
nodes[length++] = node;
}
/** array , v1 v2
*
**/
void findSmallest2ValueInArray(int *array, int length, int *v1, int *v2, int *v1Pos, int *v2Pos){
int t = 0;
for(int i = 0; i < length; i++){
if(array[i] < 0)
continue;
++t;
if(t == 1){
*v1 = array[i];
*v1Pos = i;
}else if (t == 2){
*v2 = array[i];
*v2Pos = i;
}else{
if(*v1 > array[i]){
if(*v1 < *v2){
*v2 = *v1;
*v2Pos = *v1Pos;
}
*v1 = array[i];
*v1Pos = i;
}else if(*v2 > array[i]){
*v2 = array[i];
*v2Pos = i;
}
}
}
}
/**
* Tree node 。 huffman 。
*
**/
int findNodePosViaNode(Node *node){
for(int i = 0; i < length; i++){
if(nodes[i] == node){
return i;
}
}
return -1;
}
/**
* Tree Weight node , node parent。 。
*
**/
int findNodePosViaWeight(int value, bool isForParent, bool isTheSameWeightNode){
for(int i = 0; i < length; i++){
if(nodes[i]->parent == -1 && nodes[i]->weight == value && !isForParent && !isTheSameWeightNode){
return i;
}
}
return -1;
}
/**
* 。
*
**/
int findHuffmanNodePos(){
static int mark;// 0
for(int i = mark; i < length; i++){
if(nodes[i]->lChildren == -1 && nodes[i]->rChildren == -1){
mark = i + 1;
return i;
}
}
return -1;
}
/**
* node
*
**/
Node* getNode(Node *node, int value, int parent, int lChildren, int rChildren, bool isForParent, bool isTheSameWeightNode){// , , v1 20,
// v1 , v2 20.
// v2 new 。
if(node){
cout<<"getNode , NULL"<<endl;
return NULL;
}
int pos = findNodePosViaWeight(value, isForParent, isTheSameWeightNode);
if(pos != -1){
node = nodes[pos];
}else{
node = new Node(value, parent, lChildren, rChildren);
}
return node;
}
/**
* -1 。
*
**/
void initArray2Zero(int *array, int length){
for(int i = 0; i < length; i++){
array[i] = -1;
}
}
/**
* int
*/
void printIntArray(int *array, int length){
cout<<"[";
for(int i = 0; i < length - 1; i++){
cout<<array[i]<<", ";
}
cout<<array[length - 1]<<"]"<<endl;
}
/**
*for debug
*/
void debug(int i){
cout<<"debug "<<i<<endl;
}
/**
* huffman huffman 。
*/
char** generateHuffmanCodec(int num){
int topIndex = 0;
huffmanCodec = new char*[num];//
for(int i = 0; i < num; i++){
int index = 0;
char *data = new char[num + 1];//
int thisPos = findHuffmanNodePos();
Node *currentNode = nodes[thisPos];
while(currentNode->parent != -1){
Node *currentParent = nodes[currentNode->parent];
if(thisPos == currentParent->lChildren){//0
data[index++] = '0';
}else if(thisPos == currentParent->rChildren){//1
data[index++] = '1';
}else{//X, never in.
data[index++] = 'X';
}
thisPos = currentNode->parent;
currentNode = currentParent;
}
data[index] = '\0';
huffmanCodec[topIndex++] = data;
}
return huffmanCodec;
}
public:
/**
* 。
*
**/
void makeTree(int num, ...){
int weightArray[num];
initArray2Zero(weightArray, num);
va_list list;
va_start(list, num);
for(int i = 0; i < num; i++){
weightArray[i] = va_arg(list, int);
}
va_end(list);
printIntArray(weightArray, num);//debug
int debug_x = 100;
while(true){
int v1 = -1, v2 = -1, v1Pos = -1, v2Pos = -1;
findSmallest2ValueInArray(weightArray, num, &v1, &v2, &v1Pos, &v2Pos);
if(v1 == -1 || v2 == -1){
cout<<"v1 v2 -1, "<<endl;
break;
}
Node *node1 = NULL;
node1 = getNode(node1, v1, -1, -1, -1, false, false);
addNode(node1);// add。
Node *node2 = NULL;
node2 = getNode(node2, v2, -1, -1, -1, false, v1 == v2);// v1 v2 , force, 2 , 。
addNode(node2);
Node *parent = NULL;
parent = getNode(parent, v1 + v2, -1, -1, -1, true, false);// , parent。 parent, , new 。
// 。 parent , 。
addNode(parent);
node1->parent = findNodePosViaNode(parent);
node2->parent = node1->parent;
parent->lChildren = findNodePosViaNode(node1);
parent->rChildren = findNodePosViaNode(node2);
weightArray[v1Pos] = -1;
weightArray[v2Pos] = v1 + v2;
printIntArray(weightArray, num);//debug
}
mNum = num;
generateHuffmanCodec(num);
}
/**
* huffman
*
**/
void printTree(){
for(int i = 0; i < length; i++){
cout<<"pos = "<<i<<", ";
nodes[i]->printNode();
//cout<<findHuffmanNodePos()<<endl;
}
}
/**
*
*/
void printHuffman(){
cout<<"------huffman codec begin-----
";
for(int i = 0; i < mNum; i++){
cout<<huffmanCodec[i]<<endl;
}
cout<<"------huffman codec end-----
";
}
/**
*
*/
Tree(): nodes(new Node*[100]), huffmanCodec(NULL), length(0), rPos(-1), mNum(0){// int ? Node*, , int 。
}
~Tree(){
cout<<" "<<endl;
delete []nodes;
if(huffmanCodec)
delete []huffmanCodec;
}
};
int main(){
Tree *tree = new Tree;
tree->makeTree(8, 5, 29, 7, 8, 14, 23, 3, 11);
tree->printTree();
tree->printHuffman();
delete tree;
}
책의 예는 겨우 30줄 코드인데 300줄을 썼는데 왜 이러지? 이상해. 수련이 부족할 것 같아.노력해야 돼!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[SwiftUI]List화한 CoreData를 가로 스와이프로 행 삭제하는 방법상당히 조사했지만 일본어 자료가 없었기 때문에 비망록으로 남겨 둔다. 아래와 같이 CoreData를 참조한 리스트를 가로 스와이프로 삭제하고 싶었다. UI 요소뿐만 아니라 원본 데이터 당 삭제합니다. 잘 다른 페이지...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.