网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
#include
#include
#include
#include <unordered_map>
#include
using namespace std;
class HuffmanCode {
private:
/**
-
text 文本串
-
code 产生的哈夫曼编码
*/
string text, code;
// 记录每一个字符的频数
unordered_map<char, int> weight;
// 构造一个双射 char 存的是字符 string 存的是经过哈夫曼算法的编码
unordered_map<char, string> dictionary;
unordered_map<string, char> _dictionary;
// 哈曼树的内部节点
struct Node {
// 左右孩子
Node *left, *right;
// 节点存的字符
char c;
// 频数
int val;
Node(int val, char c, Node *left = nullptr, Node *right = nullptr) : val(val), left(
left), right(right), c© {}
};
struct cmp {
bool operator()(Node *pa, Node *pb) {
return pa->val > pb->val;
}
};
void buildTreeAndDictionary() {
for (char c:text) {
weight[c]++;
}
// 最大堆,但是节点的比较用的是 >,实际上是小根堆,符合哈夫曼树的原则
priority_queue<Node *, vector<Node *>, cmp> pq;
for (const auto &it:weight) {
pq.push(new Node(it.second, it.first));
}
while (pq.size() > 1) {
Node *pa = pq.top();
pq.pop();
Node *pb = pq.top();
pq.pop();
Node *fa = new Node(pa->val + pb->val, ’ ', pa, pb);
pq.push(fa);
}
Node *root = pq.top();
dfs(root, “”);
}
// 编码过程
// 遍历所有叶子节点得到字符对应的编码
// 顺便析构
void dfs(Node *root, const string &s) {
if (root == nullptr) return;
if (root->left == nullptr && root->right == nullptr) {
dictionary[root->c] = s;
delete root;
return;
}
// 向左走为0 ,向右走位1
dfs(root->left, s + “0”);
dfs(root->right, s + “1”);
delete root;
}
//压缩
void getCompressedCode() {
string ans;
for (char c:text) {
ans += dictionary[c];
}
code = ans;
}
public:
explicit HuffmanCode(string text) : text(std::move(text)) {
buildTreeAndDictionary();
getCompressedCode();
}
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新