输出字符串的哈弗曼编码
2017-06-18 02:21
190 查看
// huffman_code.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <string>
#include "sstream"
#include <iostream>
using namespace std;
//定义单链表节点用于频数统计
typedef struct linknode *p;
typedef struct linknode
{
string s;
int value = 1;
p next;
}linknode, *link;
//定义树网单节点用于求解哈弗曼树(树网的定义见笔记)
typedef struct treenode *Ptotree;
typedef struct treenode
{
string s;
int value;
Ptotree left;
Ptotree right;
}treenode, *tree;
typedef struct treenetnode *PtoNode;
typedef struct treenetnode
{
PtoNode next;
tree root;
}treenetnode, *treenet;
//定义一个链表用于存储哈弗曼编码表
typedef struct codenode *Ptocode;
typedef struct codenode
{
string s1;//字符
string s2;//字符编码
Ptocode next;
}codenode, *code;
//函数声明
link count(string ss);
tree build_tree(link c);
void read(tree root, code list, string str);
string haffman_code(string ss);
int _tmain(int argc, _TCHAR* argv[])
{
cout << "请输入字符串:";
string s;
cin >> s;
string s_back;
s_back=haffman_code(s);
cout << "打印字符串编码:";
cout << s_back << endl;
return 0;
}
//统计字符串的各个字符的频数
link count(string ss)
{
link counthead = new linknode;
counthead->next = NULL;
link xlink;
int i = 1;
// istringstream iss(ss);
string s0;
int len = ss.length();
bool flag = false;
while (i <= len)
{
s0 = ss.at(i - 1);
i++;
// iss >> s0;
xlink = counthead;
while (xlink->next != NULL)
{
if (s0 == xlink->next->s)
{
xlink->next->value += 1;
flag = true;
break;
}
xlink = xlink->next;
}
if (flag == false)
{
link newlink = new linknode;
newlink->s = s0;
newlink->next = counthead->next;
counthead->next = newlink;
}
flag = false;
}
return counthead;
}
//定义一个树网根据权值的排序函数
treenet sort(treenet nethead)
{
treenet netx = nethead;
treenet nety;
tree x;//用于存储交换的树
while (netx != NULL)
{
nety = netx->next;
while ((nety != NULL))
{
if (nety->root->value < netx->root->value)
{
//满足交换条件时前后交换节点指向的树,节点位置关系不变
x = nety->root;
nety->root = netx->root;
netx->root = x;
}
nety = nety->next;
}
netx = netx->next;
}
return nethead;
}
//根据权值建立哈弗曼树
tree build_tree(link c)
{
treenet nethead = new treenetnode;
// nethead->root->s = c->s;
// nethead->root->value = c->value;
c = c->next;
nethead->next = NULL;
//先录入字符和权值
while (c != NULL)
{
treenet p = new treenetnode;
tree p_root = new treenode;
p->root = p_root;
p->root->s = c->s;
p->root->value = c->value;
p->root->left = NULL;
p->root->right = NULL;
p->next = nethead->next;
nethead->next = p;
c = c->next;
}
if (nethead->next == NULL)
{
cout << "输入的待编码内容为空" << endl;
return 0;
}
nethead = nethead->next;
//排序取前两个,结束条件是nethead->next=null
while (nethead->next != NULL)
{
nethead = sort(nethead);
tree add_tree = new treenode;
treenet min_tree = new treenetnode;
add_tree->left = nethead->root;
add_tree->right = nethead->next->root;
add_tree->value = nethead->root->value + nethead->next->root->value;
nethead->root = add_tree;//树合成
min_tree = nethead->next;
nethead->next = min_tree->next;
free(min_tree);//树删除
}
return nethead->root;
}
//遍历编码,先序递归
/*solution one*/
void read(tree root, code list, string str)
{
if (root->left != NULL)
{
str += "0"; read(root->left, list, str); str.erase(str.length() - 1, 1);
str += "1"; read(root->right, list, str); str.erase(str.length() - 1, 1);
}
else
{
code newnode = new codenode;
newnode->s1 = root->s;
newnode->s2 = str;
newnode->next = list->next;
list->next = newnode;
}
}
string haffman_code(string ss)
{
//统计频数
link linkhead = new linknode;
linkhead->next = NULL;
linkhead = count(ss);
//构建哈弗曼树
tree treehead = new treenode;
treehead->left = NULL;
treehead->right = NULL;
treehead = build_tree(linkhead);
//编写哈弗曼编码表
code listhead = new codenode;
listhead->next = NULL;
string str;
read(treehead, listhead, str);
//输出编码表
cout << "打印编码表:" << endl;
code xlist = listhead->next;
while (xlist != NULL)
{
cout << xlist->s1 << " " << xlist->s2 << endl;
xlist = xlist->next;
}
//输出字符串对应的哈弗曼编码
int i = 0;
code listx;
string ss_back;
while (i < ss.length())
{
str = ss.at(i);
listx = listhead->next;
while (listx != NULL)
{
if (listx->s1 == str)
{
ss_back += listx->s2;
break;
}
listx = listx->next;
}
i++;
}
return ss_back;
}
//
#include "stdafx.h"
#include <string>
#include "sstream"
#include <iostream>
using namespace std;
//定义单链表节点用于频数统计
typedef struct linknode *p;
typedef struct linknode
{
string s;
int value = 1;
p next;
}linknode, *link;
//定义树网单节点用于求解哈弗曼树(树网的定义见笔记)
typedef struct treenode *Ptotree;
typedef struct treenode
{
string s;
int value;
Ptotree left;
Ptotree right;
}treenode, *tree;
typedef struct treenetnode *PtoNode;
typedef struct treenetnode
{
PtoNode next;
tree root;
}treenetnode, *treenet;
//定义一个链表用于存储哈弗曼编码表
typedef struct codenode *Ptocode;
typedef struct codenode
{
string s1;//字符
string s2;//字符编码
Ptocode next;
}codenode, *code;
//函数声明
link count(string ss);
tree build_tree(link c);
void read(tree root, code list, string str);
string haffman_code(string ss);
int _tmain(int argc, _TCHAR* argv[])
{
cout << "请输入字符串:";
string s;
cin >> s;
string s_back;
s_back=haffman_code(s);
cout << "打印字符串编码:";
cout << s_back << endl;
return 0;
}
//统计字符串的各个字符的频数
link count(string ss)
{
link counthead = new linknode;
counthead->next = NULL;
link xlink;
int i = 1;
// istringstream iss(ss);
string s0;
int len = ss.length();
bool flag = false;
while (i <= len)
{
s0 = ss.at(i - 1);
i++;
// iss >> s0;
xlink = counthead;
while (xlink->next != NULL)
{
if (s0 == xlink->next->s)
{
xlink->next->value += 1;
flag = true;
break;
}
xlink = xlink->next;
}
if (flag == false)
{
link newlink = new linknode;
newlink->s = s0;
newlink->next = counthead->next;
counthead->next = newlink;
}
flag = false;
}
return counthead;
}
//定义一个树网根据权值的排序函数
treenet sort(treenet nethead)
{
treenet netx = nethead;
treenet nety;
tree x;//用于存储交换的树
while (netx != NULL)
{
nety = netx->next;
while ((nety != NULL))
{
if (nety->root->value < netx->root->value)
{
//满足交换条件时前后交换节点指向的树,节点位置关系不变
x = nety->root;
nety->root = netx->root;
netx->root = x;
}
nety = nety->next;
}
netx = netx->next;
}
return nethead;
}
//根据权值建立哈弗曼树
tree build_tree(link c)
{
treenet nethead = new treenetnode;
// nethead->root->s = c->s;
// nethead->root->value = c->value;
c = c->next;
nethead->next = NULL;
//先录入字符和权值
while (c != NULL)
{
treenet p = new treenetnode;
tree p_root = new treenode;
p->root = p_root;
p->root->s = c->s;
p->root->value = c->value;
p->root->left = NULL;
p->root->right = NULL;
p->next = nethead->next;
nethead->next = p;
c = c->next;
}
if (nethead->next == NULL)
{
cout << "输入的待编码内容为空" << endl;
return 0;
}
nethead = nethead->next;
//排序取前两个,结束条件是nethead->next=null
while (nethead->next != NULL)
{
nethead = sort(nethead);
tree add_tree = new treenode;
treenet min_tree = new treenetnode;
add_tree->left = nethead->root;
add_tree->right = nethead->next->root;
add_tree->value = nethead->root->value + nethead->next->root->value;
nethead->root = add_tree;//树合成
min_tree = nethead->next;
nethead->next = min_tree->next;
free(min_tree);//树删除
}
return nethead->root;
}
//遍历编码,先序递归
/*solution one*/
void read(tree root, code list, string str)
{
if (root->left != NULL)
{
str += "0"; read(root->left, list, str); str.erase(str.length() - 1, 1);
str += "1"; read(root->right, list, str); str.erase(str.length() - 1, 1);
}
else
{
code newnode = new codenode;
newnode->s1 = root->s;
newnode->s2 = str;
newnode->next = list->next;
list->next = newnode;
}
}
string haffman_code(string ss)
{
//统计频数
link linkhead = new linknode;
linkhead->next = NULL;
linkhead = count(ss);
//构建哈弗曼树
tree treehead = new treenode;
treehead->left = NULL;
treehead->right = NULL;
treehead = build_tree(linkhead);
//编写哈弗曼编码表
code listhead = new codenode;
listhead->next = NULL;
string str;
read(treehead, listhead, str);
//输出编码表
cout << "打印编码表:" << endl;
code xlist = listhead->next;
while (xlist != NULL)
{
cout << xlist->s1 << " " << xlist->s2 << endl;
xlist = xlist->next;
}
//输出字符串对应的哈弗曼编码
int i = 0;
code listx;
string ss_back;
while (i < ss.length())
{
str = ss.at(i);
listx = listhead->next;
while (listx != NULL)
{
if (listx->s1 == str)
{
ss_back += listx->s2;
break;
}
listx = listx->next;
}
i++;
}
return ss_back;
}
相关文章推荐
- 输出某种编码的字符串
- 我们在web应用开发过程中经常遇到输出某种编码的字符,如iso8859-1等,如何输出一个某种编码的字符串?
- Razor视图引擎输出没有编码的 Html 字符串
- 输入字符串输出Unicode编码
- 如何输出某种编码的字符串,比如ISO-8859-1?
- UCS-2与UTF8之间的选择(3)--windows中各编码字符串的C/C++输出支持及方式比较
- 我们在 web 应用开发过程中经常遇到输出某种编码的字 符, 如 iso8859-1 等, 如何输出一个某种编码的字符串?
- 请设计一个算法,给一个字符串进行二进制编码,使得编码后字符串的长度最短。(哈弗曼编码)
- 【转】使用MvcHtmlString类输出不经过编码的HTML字符串
- js对图片base64编码字符串进行解码并输出图像示例
- JS 对图片base64编码字符串进行解码并输出图像
- 改变mysql客户端输出的字符串编码
- C# .net Emoji字体 Unicode编码转UTF16内码字符串输出
- 输出某种编码的字符串
- js对图片base64编码字符串进行解码并输出图像示例
- 华为编程题之五:输入一个正整数,并编码为字符串进行输出
- python 2.7输出中文字符串的编码问题
- ASP.NET MVC Razor 输出没有编码的HTML字符串
- Python入门(二)——IDE选择PyCharm,输入和输出,基础规范,数据类型和变量,常量,字符串和编码,格式化
- 如何输出一个某种编码的字符串?