計算機系統結構---指令編碼

【實驗目的與要求】
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();//擴展編碼
}

運行結果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章