【实验目的与要求】
1、熟练掌握指令操作码采用等长码、哈夫曼码、扩展码的编码方法。
2、在已知指令个数和频度的基础上,要求用程序实现等长码、哈夫曼码、扩展码的编码,实验结束后提交源程序和实验说明书。
【实验内容】
了解和掌握指令编码的基本原理和要求,在已知指令个数和频度的前提上,要求用程序实现等长码、哈夫曼码(选做)、扩展码的编码,并计算出平均码长。
【实验步骤】
1.按提示输入处理机的指令条数和使用频度。
3.求出等长码的编码,并计算出平均码长。
4.使用哈夫曼编码方法,求出编码和平均码长(选做)。
5.根据指令个数和使用频度,分析扩展码的扩展格式,并求出编码和平均码长。
6.要设计出简洁、直观、易于操作的界面。
【源代码】
// Test1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//编码方式
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
static int n;//记录指令条数
static char Data[50];//记录需要编码的字符
static float Freq[50];//记录使用频度
static int Bin[50];//保存二进制编码
void Binary(int t) {//求解二进制编码
int i = 0;
while (t) {
int p = t % 2;
t /= 2;
Bin[i++] = p;
}
}
void Binary(int t,int n) {//求解二进制编码
int i = n;
if (t == 0) {
Bin[i++] = 0;
}
while (t) {
int p = t % 2;
t /= 2;
Bin[i++] = p;
}
}
void EquL() {//等长编码
int num = ceil(log(n) / log(2));//对指令条数进行对数运算向上取整。
cout << endl << "等长编码的结果为:" << endl;
for (int i = 0; i < n; i++) {
Binary(i);
cout << Freq[i] << " ";
for (int j = num - 1; j >= 0; j--) {
cout << Bin[j];
}
cout << endl;
}
cout << "平均码长为:" << num << endl << endl;
}
bool cmp(float x, float y) {//从大到小
return x > y;
}
void Extend() {//扩展编码
cout << "=============扩展编码:============\n\n";
for (int i = 0; i < n; i++) {
Bin[i] = 0;
}
sort(Freq, Freq + n, cmp);
for (int i = 0; i < n; i++) {
cout << Freq[i] << " ";
}
cout << endl;
int t = 0;
int w;
int num = ceil(log(n) / log(2));//最多需要的位数
float max = 100;
int d, c, dn, cn;
d = c = dn = cn = 0;
for (int i = 1; i < num; i++) {//i记录短码的位数
w = pow(2, i);//短码最多可表示的个数
for (int j = 1; j < w; j++) {//j表示短码表示的个数
float sum = 0;
int surplus = 0;
int num1 = 0;
surplus = n - j;//短码表示后剩余需要编码的个数
int pt = surplus / (w - j);//需要扩展的位数
num1 = ceil(log(pt) / log(2));//最少需要的位数
if (num1 == 0) {
num1 += 1;
}
num1 += i;//这里的num1表示长码的位数
for (int k = 0; k < n; k++) {
if (k < j) {
sum += Freq[k] * i;
}
else {
sum += Freq[k] * num1;
}
}
if (sum < max) {
max = sum;
d = i;
c = num1;
dn = j;
cn=surplus;
}
cout <<"短码位数:"<<i<<"\t长码位数:"<<num1<<"\t平均码长:"<< sum<<"\t\t";
cout << "短码个数:" << j << "\t长码个数:" << surplus << endl;
}
}
cout << "\n=============最优结果为:=========" << endl << endl;
cout << "短码位数:" << d << "\t长码位数:" << c << "\t短码编码个数:" << dn << "\t长码编码个数:" << cn << "\t平均码长:" << max << endl;
cout << "编码结果:" << endl;
w= pow(2, d);//短码位数最多可表示的数
int numc = 0;
for (int i = 0; i < dn; i++) {
Binary(i);
cout << Freq[i] << " ";
for (int j = d - 1; j >= 0; j--) {
cout << Bin[j];
}
cout << endl;
}
numc = dn;
for (int i = dn; i < w; i++) {
Binary(i);
if (numc <= n) {
for (int j = 0; j < pow(2, c - d); j++) {
Binary(j,d);
cout << Freq[numc++] << " ";
for (int k = d -1; k >= 0; k--) {
cout << Bin[k];
}
for (int k = c - 1; k >= d; k--) {
cout << Bin[k];
}
cout << endl;
}
}
}
}
int main()
{
cout << "请输入指令条数:";
cin >> n;
cout << "请输入使用频度:" << endl;
for (int i = 0; i < n; i++) {
cin >> Freq[i];
}
EquL();//等长编码
Extend();//扩展编码
}
运行结果: