无损编码——算术编码

最近随手写了下算术编码,放在这里权当记录。使用了类封装——ArithmeticCoding
ArithmeticCoding.h

#pragma once
#include <iostream>
using namespace std;
#define M 100
#define N 128
class ArithmeticCoding
{
public:
	int count, length,total;
	char para[N], n;
	long double probablity[N], c;
	char code[M];
	long double High, Low, high, low, d = 1.0, result;
	ArithmeticCoding();
	~ArithmeticCoding();

	void get_para();
	void get_code();
	void coding();
	void decoding();
};


ArithmeticCoding.cpp

#include "ArithmeticCoding.h"



ArithmeticCoding::ArithmeticCoding()
{
	High = 0; Low = 0;
}


ArithmeticCoding::~ArithmeticCoding()
{
}

void ArithmeticCoding::get_para()
{
	int num = 0;
	cout << "请输入编码种类总数" << endl;
	cin >> num;
	total = num;
	cout << "请输入数据及概率" << endl;
	for (int i = 0; i<num; i++)
	{
		cin >> n >> c;
		para[i] = n;
		probablity[i] = c;
	}
}

void ArithmeticCoding::get_code()
{
	cout << "请输入编码的长度"<<endl;
	cin >> length;
	while (length >= M)
	{
		cout << "超过最大编码长度,请重新输入";
		cin >> length;
	}
	cout << "请输入待编码数据:";
	for (int i = 0; i<length; i++)
	{
		cin >> code[i];
	}
}
void ArithmeticCoding::decoding()
{
	long double res = 0;
	int nn = 0;
	cout << "请输入待解码数据" << endl;
	cin >> res;
	cout << "请输入解码位数" << endl;
	cin >> nn;
	double high = 1.0, low = 0.0, now = 0.0;
	for (int i = 0; i < nn; i++)
	{
		
		now = (res-low) / (high - low);
		//cout <<"now:"<< now << " res:" << res << " low:" << low << " high:" << high << endl;
		double sum = 0.0;
		for (int j = 0; j < total; j++)
		{
			sum = sum + probablity[j];
			if (now <= sum)
			{
				cout << para[j];
				double h = high, l = low;
				high = l+sum*(h-l);
				low = high-probablity[j]*(h-l);
				break;
			}
		}
	}
	cout << endl;

}
void ArithmeticCoding::coding()
{
	this->get_code();
	int i, j = 0;
	for (i = 0; i<length; i++)
		if (code[0] == para[i]) break;
	while (j < i) {
		Low = Low + probablity[j];
		j++;
	}
	d = probablity[j];
	High = Low + d;
	for (i = 1; i<length; i++)
		for (j = 0; j<total; j++)
		{
			if (code[i] == para[j])
			{
				if (j == 0)
				{
					low = Low;
					high = Low + probablity[j] * d;
					High = high;
					d *= probablity[j];
				}
				else
				{
					float chance_l = 0.0;
					for (int k = 0; k <= j - 1; k++)
						chance_l += probablity[k];
					low = Low + d*chance_l;
					high = Low + d*(chance_l + probablity[j]);
					Low = low;
					High = high;
					d *= probablity[j];
				}
			}
			else continue;
		}
	cout << "结果是:" << Low << endl;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值