博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实用算法实现-第 11 篇 贪心算法
阅读量:7062 次
发布时间:2019-06-28

本文共 3191 字,大约阅读时间需要 10 分钟。

11.1    Huffman编码

Huffman设计了一个可以用来构造一种称为Huffman编码的最优前缀码的贪心算法。

11.1.1   实例

PKU JudgeOnline, 1521, Entropy.

11.1.2   问题描述

给定一组ASCII码组成的字符串,求用Huffman编码该字符串所需的长度,及采用该编码带来的压缩比。

11.1.3   输入

AAAAABCD

THE_CAT_IN_THE_HAT

END

11.1.4   输出

6413 4.9

144 51 2.8

11.1.5   分析

采用贪心算法,使用最小堆就可以实现Huffman树的构建。为了便于计算每种字符对应的码的长度,用update()维护depth数组。如果需要求出每种字符对应的编码,只需要进一步增强update()函数即可。

注意:对于只有同一种字符的字符串要特殊处理。

11.1.6   程序

#include <iostream> #include <stdio.h> #include <string.h> using namespace std; #define maxNum ('_' - 'A' + 1) #define MAX 0x7F7F7F7F struct node{ int key; int pos; }; nodeminHeap[maxNum]; int heapSize; void minHeapify(int i) { int l; int r; int min; node temp; l = i * 2; r = i * 2 + 1; min = i; if((l <=heapSize)&& (minHeap[l].key < minHeap[min].key)){ min = l; } if((r <=heapSize)&& (minHeap[r].key < minHeap[min].key)){ min = r; } if(min !=i) { temp = minHeap[min]; minHeap[min] = minHeap[i]; minHeap[i] = temp; minHeapify(min); } } void buildMinHeap() { int i; for(i =heapSize / 2; i > 0; i--){ minHeapify(i); } } nodeheapExtractMin() { node min; if(heapSize< 1) { cout << "ERROR:no more" << endl; } min = minHeap[1]; minHeap[1] = minHeap[heapSize]; heapSize--; minHeapify(1); return min; } void heapIncreaseKey(int i, int key) { node temp; if(key >minHeap[i].key) { cout << "ERROR:new key is smaller than current key" << endl; } minHeap[i].key = key; while(i> 1 && minHeap[i/2].key > minHeap[i].key) { temp = minHeap[i]; minHeap[i] = minHeap[i/2]; minHeap[i/2] = temp; i = i / 2; } } void minHeapInsert(node temp) { heapSize++; minHeap[heapSize] = temp; minHeap[heapSize].key = MAX; heapIncreaseKey(heapSize, temp.key); } int f[maxNum + maxNum]; int huffmanLeft[maxNum + maxNum]; int huffmanRight[maxNum + maxNum]; int depth[maxNum]; int huffmanTop; void update(int x) { if(x <0) { return; } if(x <maxNum){ depth[x]++; return; } update(huffmanLeft[x]); update(huffmanRight[x]); } int huffman() { node x; node y; node z; huffmanTop = maxNum; while(heapSize> 1){ x = heapExtractMin(); y = heapExtractMin(); z.pos = huffmanTop; huffmanLeft[z.pos] = x.pos; huffmanRight[z.pos] = y.pos; z.key = x.key + y.key; f[z.pos] = f[x.pos] + f[y.pos]; minHeapInsert(z); update(x.pos); update(y.pos); huffmanTop++; } z = heapExtractMin(); if(z.pos !=huffmanTop - 1) { int *a= (int *)0; *a = 0; printf("error\n"); } returnz.pos; } int main() { charstr[10000]; int pos; int length; int sum; int i; int n; while(scanf("%s", str)){ if(strcmp("END", str) == 0) { break; } memset(f, 0, sizeof(f)); memset(minHeap, 0, sizeof(minHeap)); length = strlen(str); n = 0; for(i =0; i < length; i++){ pos = str[i] - 'A'; if(f[pos]== 0) { n++; } f[pos]++; } pos = 1; for(i =0; i < maxNum; i++){ if(f[i]!= 0){ minHeap[pos].key = f[i]; minHeap[pos].pos = i; pos++; } } if(n> 1){ heapSize = n; buildMinHeap(); memset(huffmanLeft, 0xff, sizeof(huffmanLeft)); memset(huffmanRight, 0xff, sizeof(huffmanRight)); memset(depth, 0, sizeof(depth)); huffman(); sum = 0; for(i= 0; i < maxNum; i++){ sum += depth[i] * f[i]; } }else{ sum = length; } length = length * 8; printf("%d%d %.1f\n", length, sum, (double)length/ sum); } }
本文章欢迎转载,请保留原始博客链接http://blog.csdn.net/fsdev/article

转载于:https://www.cnblogs.com/jpa2/archive/2011/10/20/2527912.html

你可能感兴趣的文章
面向对象第四次博客
查看>>
【BZOJ4870】组合数问题 [矩阵乘法][DP]
查看>>
封装分页存储过程
查看>>
http缓存浅谈
查看>>
(转)内存堆和栈的区别
查看>>
{...formItemLayout} 标签布局
查看>>
vue2.0 仿手机新闻站(四)axios
查看>>
每个java初学者都应该搞懂的问题
查看>>
如何处理来自 Web Service 客户端的未知 SOAP 标头
查看>>
棒球记录系统
查看>>
malloc函数
查看>>
[转]自动消失提示框
查看>>
推荐大家一个CSS书写规范
查看>>
How to Add a Binary Stream Image to ListView Columns
查看>>
考研倒计时
查看>>
蓝桥杯 【基础练习】 01字串
查看>>
HTTPS 原理解析(转)
查看>>
测试近五年有感
查看>>
【AtCoder】【DP】【思维】Prefix Median(AGC012)
查看>>
swiper轮播图(逆向自动切换类似于无限循环)
查看>>