哈夫曼编码,应用模板特化递归+bind函数绑定
来源:互联网 发布:java windows api 编辑:程序博客网 时间:2024/06/09 02:22
- 文件列表
- BTreehpp
- HuffmanTreehpp
- HuffmanTreecpp
- Testcpp
- 模板特化递归
- bind 函数绑定
- 后记
文件列表
BTree.hpp
#ifndef __BTREE__#define __BTREE__#include <iostream>#include <functional>template <typename K,typename V>class BTree{public: BTree() { is_leaf = false; parent = nullptr; left_child = nullptr; right_child = nullptr; } BTree(bool _is_leaf) { is_leaf = _is_leaf; parent = nullptr; left_child = nullptr; right_child = nullptr; } void Set_Parent(BTree<K,V>* _parent); void Set_Left_Child(BTree<K,V>* _left_child); void Set_Right_Child(BTree<K,V>* _right_child); BTree<K,V>* Get_Parent(); BTree<K,V>* Get_Left_Child(); BTree<K,V>* Get_Right_Child(); void Set_Key(K _key); void Set_Value(V _value); K Get_Key(); V Get_Value(); bool Is_Leaf() { return is_leaf; }private: BTree<K,V>* parent; BTree<K,V>* left_child; BTree<K,V>* right_child; K key; V value; bool is_leaf;};template <typename K,typename V>void BTree<K,V>::Set_Parent(BTree<K,V>* _parent){ parent = _parent;}template <typename K,typename V>void BTree<K,V>::Set_Left_Child(BTree<K,V>* _left_child){ left_child = _left_child;}template <typename K,typename V>void BTree<K,V>::Set_Right_Child(BTree<K,V>* _right_child){ right_child = _right_child;}template <typename K,typename V>BTree<K,V>* BTree<K,V>::Get_Parent(){ return parent;}template <typename K,typename V>BTree<K,V>* BTree<K,V>::Get_Left_Child(){ return left_child;}template <typename K,typename V>BTree<K,V>* BTree<K,V>::Get_Right_Child(){ return right_child;}template <typename K,typename V>void BTree<K,V>::Set_Key(K _key){ key = _key;}template <typename K,typename V>void BTree<K,V>::Set_Value(V _value){ value = _value;}template <typename K,typename V>K BTree<K,V>::Get_Key(){ return key;}template <typename K,typename V>V BTree<K,V>::Get_Value(){ return value;}template <typename K,typename V>void Traverse(BTree<K,V>* _btree){ if(_btree->Is_Leaf()) { // std::cout << _btree->Get_Key() << " " << _btree->Get_Value() << std::endl; return; } else { if(_btree->Get_Left_Child()) { // std::cout << "push_back 0" << std::endl; Traverse(_btree->Get_Left_Child()); // std::cout << "pop_back 0" << std::endl; } if(_btree->Get_Right_Child()) { // std::cout << "push_back 1" << std::endl; Traverse(_btree->Get_Right_Child()); // std::cout << "pop_back 1" << std::endl; } }}template <typename K,typename V>void Traverse(BTree<K,V>* _btree,std::function<void(char)> _operation_push,std::function<void(char)> _operation_pop,std::function<void(char)> _operation_check){ if(_btree->Is_Leaf()) { _operation_check(_btree->Get_Key()); return; } else { if(_btree->Get_Left_Child()) { _operation_push('0'); Traverse(_btree->Get_Left_Child(),_operation_push,_operation_pop,_operation_check); _operation_pop('0'); } if(_btree->Get_Right_Child()) { _operation_push('1'); Traverse(_btree->Get_Right_Child(),_operation_push,_operation_pop,_operation_check); _operation_pop('1'); } }}#endif
HuffmanTree.hpp
#ifndef __HUFFMANTREE__#define __HUFFMANTREE__#include "BTree.hpp"#include <string>#include <vector>#include <stack>#include <queue>#include <map>using namespace std;class HuffmanTree{public: HuffmanTree(); HuffmanTree(string _info); void Set_Info(string _info); string Encode(string _str); string Decode(string _code);private: void Build_Tree(); void Encode_Assistant_Push(char _code); void Encode_Assistant_Pop(char _code); void Encode_Assistant_Check(char _original_char,char _tree_char); string info; string encode; string sub_code; string decode; BTree<char,unsigned int>* huffman_tree;};#endif
HuffmanTree.cpp
#include "HuffmanTree.hpp"using namespace std;HuffmanTree::HuffmanTree(){ huffman_tree = nullptr;}HuffmanTree::HuffmanTree(string _info){ huffman_tree = nullptr; info = _info; Build_Tree();}void HuffmanTree::Set_Info(string _info){ info = _info; Build_Tree();}void HuffmanTree::Build_Tree(){ map<char,unsigned int> key_value; for(auto i:info) { bool inside = false; for(auto index_map = key_value.begin();index_map != key_value.end();++index_map) { if(i == index_map->first) { index_map->second++; inside = true; break; } } if(inside) { continue; } key_value.insert(pair<char,unsigned int>(i,1)); } vector<char> key_vector; for(auto i = key_value.begin();i != key_value.end();++i) { key_vector.push_back(i->first); } stack<char> key_stack; while(!key_vector.empty()) { auto it = vector<char>::iterator(); char key; int max_time = 0; for(auto i = key_vector.begin();i != key_vector.end();++i) { if(key_value[*i] > max_time) { key = *i; it = i; max_time = key_value[*i]; } } key_stack.push(*it); key_vector.erase(it); } queue<BTree<char,unsigned int>*> sum_node_queue; while(!key_stack.empty()) { BTree<char,unsigned int>* left_node = new BTree<char,unsigned int>(true); left_node->Set_Key(key_stack.top()); left_node->Set_Value(key_value[key_stack.top()]); key_stack.pop(); if(key_stack.empty()) { sum_node_queue.push(left_node); break; } BTree<char,unsigned int>* right_node = new BTree<char,unsigned int>(true); right_node->Set_Key(key_stack.top()); right_node->Set_Value(key_value[key_stack.top()]); key_stack.pop(); BTree<char,unsigned int>* sum_node = new BTree<char,unsigned int>(); sum_node->Set_Key(0); sum_node->Set_Left_Child(left_node); sum_node->Set_Right_Child(right_node); sum_node_queue.push(sum_node); } while(!sum_node_queue.empty()) { BTree<char,unsigned int>* left_node = sum_node_queue.front(); sum_node_queue.pop(); BTree<char,unsigned int>* right_node = sum_node_queue.front(); sum_node_queue.pop(); BTree<char,unsigned int>* sum_node = new BTree<char,unsigned int>(); sum_node->Set_Left_Child(left_node); sum_node->Set_Right_Child(right_node); sum_node_queue.push(sum_node); if(!(right_node != nullptr && left_node != nullptr)) { huffman_tree = left_node; } }}string HuffmanTree::Encode(string _str){ encode.clear(); for(auto i:_str) { Traverse(huffman_tree, bind(&HuffmanTree::Encode_Assistant_Push,this,placeholders::_1), bind(&HuffmanTree::Encode_Assistant_Pop,this,placeholders::_1), bind(&HuffmanTree::Encode_Assistant_Check,this,i,placeholders::_1)); } return encode;}string HuffmanTree::Decode(string _code){ decode.clear(); auto node = huffman_tree; for(auto i = _code.begin();i != _code.end();++i) { if(node->Is_Leaf()) { decode.push_back(node->Get_Key()); node = huffman_tree; i--; } else { if(*i == '0') { node = node->Get_Left_Child(); } else if(*i == '1') { node = node->Get_Right_Child(); } } } return decode;}void HuffmanTree::Encode_Assistant_Push(char _code){ sub_code.push_back(_code);}void HuffmanTree::Encode_Assistant_Pop(char _code){ sub_code.pop_back();}void HuffmanTree::Encode_Assistant_Check(char _original_char,char _tree_char){ if(_original_char == _tree_char) { encode += sub_code; }}
Test.cpp
#include "BTree.hpp"#include "HuffmanTree.hpp"#include <iostream>#include <string>using namespace std;int main(int argc, char const *argv[]){ // Test BTree // BTree<char,int>* huffman_tree = new BTree<char,int>(); // huffman_tree->Set_Key('a'); // huffman_tree->Set_Value(3); // cout << huffman_tree->Get_Key() << " " << huffman_tree->Get_Value() << " " << huffman_tree->Is_Leaf() << endl; // BTree<char,int>* huffman_tree_left_child = new BTree<char,int>(true); // huffman_tree_left_child->Set_Key('b'); // huffman_tree_left_child->Set_Value(2); // BTree<char,int>* huffman_tree_right_child = new BTree<char,int>(true); // huffman_tree_right_child->Set_Key('c'); // huffman_tree_right_child->Set_Value(2); // huffman_tree->Set_Left_Child(huffman_tree_left_child); // huffman_tree->Set_Right_Child(huffman_tree_right_child); // cout << huffman_tree->Get_Left_Child()->Get_Key() << " " << huffman_tree->Get_Left_Child()->Get_Value() << " " << huffman_tree->Get_Left_Child()->Is_Leaf() << endl; // cout << huffman_tree->Get_Right_Child()->Get_Key() << " " << huffman_tree->Get_Right_Child()->Get_Value() << " " << huffman_tree->Get_Right_Child()->Is_Leaf() << endl; // Traverse(huffman_tree); // Test HuffmanTree string test_string1 = "In computer science and information theory, "; string test_string2 = "a Huffman code is a particular type of optimal prefix code that is commonly used for lossless data compression. "; string test_string3 = "The process of finding and/or using such a code proceeds by means of Huffman coding, "; string test_string4 = "an algorithm developed by David A. Huffman while he was a Ph.D. student at MIT, and published in the 1952 paper "; string test_string5 = "\"A Method for the Construction of Minimum-Redundancy Codes\".[1] "; string test_string6 = "The output from Huffman's algorithm can be viewed as a variable-length code table for encoding a source symbol "; string test_string7 = "(such as a character in a file). The algorithm derives this table from the estimated probability or frequency of occurrence"; string test_string8 = " (weight) for each possible value of the source symbol. As in other entropy encoding methods, more common symbols are generally "; string test_string9 = "represented using fewer bits than less common symbols. Huffman's method can be efficiently implemented, "; string test_string10 = "finding a code in linear time to the number of input weights if these weights are sorted.[2] However, "; string test_string11 = "although optimal among methods encoding symbols separately, Huffman coding is not always optimal among all compression methods."; string test_string = test_string1 + test_string2 + test_string3 + test_string4 + test_string5 + test_string6 + test_string7 + test_string8 + test_string9 + test_string10 + test_string11; HuffmanTree huffman_tree(test_string); cout << "\"" << test_string << "\"" << " has been encoded as:" << endl; cout << huffman_tree.Encode(test_string) << endl; cout << "\"" << huffman_tree.Encode(test_string) << "\"" << " has been decoded as:" << endl; cout << huffman_tree.Decode(huffman_tree.Encode(test_string)) << endl; return 0;}
模板特化递归
template <typename K,typename V>void Traverse(BTree<K,V>* _btree){ if(_btree->Is_Leaf()) { // std::cout << _btree->Get_Key() << " " << _btree->Get_Value() << std::endl; return; } else { if(_btree->Get_Left_Child()) { // std::cout << "push_back 0" << std::endl; Traverse(_btree->Get_Left_Child()); // std::cout << "pop_back 0" << std::endl; } if(_btree->Get_Right_Child()) { // std::cout << "push_back 1" << std::endl; Traverse(_btree->Get_Right_Child()); // std::cout << "pop_back 1" << std::endl; } }}template <typename K,typename V>void Traverse(BTree<K,V>* _btree,std::function<void(char)> _operation_push,std::function<void(char)> _operation_pop,std::function<void(char)> _operation_check){ if(_btree->Is_Leaf()) { _operation_check(_btree->Get_Key()); return; } else { if(_btree->Get_Left_Child()) { _operation_push('0'); Traverse(_btree->Get_Left_Child(),_operation_push,_operation_pop,_operation_check); _operation_pop('0'); } if(_btree->Get_Right_Child()) { _operation_push('1'); Traverse(_btree->Get_Right_Child(),_operation_push,_operation_pop,_operation_check); _operation_pop('1'); } }}
bind 函数绑定
string HuffmanTree::Encode(string _str){ encode.clear(); for(auto i:_str) { Traverse(huffman_tree, bind(&HuffmanTree::Encode_Assistant_Push,this,placeholders::_1), bind(&HuffmanTree::Encode_Assistant_Pop,this,placeholders::_1), bind(&HuffmanTree::Encode_Assistant_Check,this,i,placeholders::_1)); } return encode;}
后记
学校里的老师基本看不懂,因为他们不懂模板特化,不懂C++11,不懂泛型思维
于是在检查的时候狠狠地装了一回逼:)
CSDN 辣鸡 MD 编辑器,无序列表格式全丢
阅读全文
0 0
- 哈夫曼编码,应用模板特化递归+bind函数绑定
- 模板函数特化
- 函数模板的特化
- 模板函数的特化
- 模板函数 重载/特化
- 函数模板的特化
- 函数模板的特化
- 函数模板的特化
- 函数模板的特化
- 函数模板特化问题-compare函数特化
- C++ 模板全特化中的函数特化
- 函数模板全特化与偏特化
- C++ 模板全特化中的函数特化
- 为什么不特化函数模板
- 函数模板特化(一)
- boost::bind 函数绑定
- bind函数绑定
- bind函数绑定
- Hdu2162 Add ‘em
- Java中方法的重写(override)和重载(overload)的使用规则总结:
- 两数组的交 II
- 基于Python库surprise的电影推荐系统
- HTML5 eclipse中写java,html,css,javascript代码提示
- 哈夫曼编码,应用模板特化递归+bind函数绑定
- c++ primer
- Linux_正则表达式
- Linux tar 命令 压缩、解压
- [DuiLib教程2]DuiLib第一个测试Demo的注释
- 【论文阅读】 Enhancing Video Event Recognition Using Automatically Constructed Semantic-Visual Knowledge
- re.sub 功能
- zoj 1012
- 在caffe中绘制ROC曲线