CCF-CSP认证202305-3:解压缩(AC代码+超详细解析)

运行结果

解题思路

很暴力的模拟题,基本不用数据结构,只要思路不乱,注意l-1就能轻松AC

数据结构方面:一个vector维护已输出的内容,一个循环queue维护需要回溯引用的内容

代码分析

输出容器 output

维护已经输出的内容,用字节对应的整数作为元素

vector output;
ll output_length = 0;

函数 CharToInt

将字节转换成整数返回

int CharToInt(char HighByte, char LowByte)
{
	int H = ('0'<=HighByte && HighByte<='9') ? HighByte-'0' : HighByte-'a'+10;
	int L = ('0'<=LowByte && LowByte<='9') ? LowByte-'0' : LowByte-'a'+10;
	return H * 16 + L;
}

函数 PrintInt

输出整数对应的字节格式,并适时输出换行

void PrintInt(int x)
{
	int H = x / 16, L = x % 16;
	char HighByte = (0<=H && H<=9) ? H+'0' : H+'a'-10;
	char LowByte = (0<=L && L<=9) ? L+'0' : L+'a'-10;
	cout<

函数 Print_ConstData

读取并输出指定长度的字面量

void Print_ConstData(ll const_l)
{
	char HighByte, LowByte;
	while(const_l--) {
		cin>>HighByte>>LowByte;
		int Byte = CharToInt(HighByte, LowByte);
		PrintInt(Byte);
		output.push_back(Byte);
	}
}

函数 Print_VarData

根据o和l输出指定长度的回溯引用,这里维护了一个循环队列,循环输出指定长度的内容

void Print_VarData(ll var_o, ll var_l)
{
	queue var_output;
	for(ll i=0; i

主函数变量定义

HighByte、LowByte、Byte存储读取到的字节和对应的整数

state记录当前的状态:“guide”意为接下来读的字节属于导引域;“finish”意为告一段落,该读入新的数据域了;“const_guide”意为接下来读的字节属于字面量的说明部分;“var_guide_1”意为接下来读的字节属于回溯引用说明部分中的形式1;“var_guide_2”意为接下来读的字节属于回溯引用说明部分中的形式2

guide_length记录导引域的字节数;data_length记录从导引域解析出来的原始数据的长度

const_l记录接下来的字面量的字节数;当l>60时,const_guide_length记录接下来有几个字节算作字面量的说明部分,const_guide_length_i记录已经读了几个字节的字面量的说明部分

var_ovar_l即题中的var_guide_lengthvar_guide_length_i的作用同上面的

int main()
{
	ios::sync_with_stdio(false);    cin.tie(0);
	char HighByte, LowByte;
	int Byte;
	string state = "guide";
	ll guide_length = 0, data_length = 0;
	ll const_length = 0, const_guide_length = 0, const_guide_length_i = 0;
	ll var_o = 0, var_l = 0, var_guide_length = 0, var_guide_length_i = 0;
	ll s;   cin>>s;
	for(ll s_length=0; s_length>HighByte>>LowByte;		Byte = CharToInt(HighByte, LowByte);
        /*
        ······
        */
    }
	return 0;
}

主函数循环中state为guide的情况

根据当下的字节是否是最后一个导引域的字节来进行更新

if(state == "guide") {
	if(Byte >= 128)
		data_length += (Byte-128) * pow(128, guide_length++);
	else {
		data_length += Byte * pow(128, guide_length++);
		state = "finish";
	}
}

主函数循环中state为finish的情况

判断当下的字节属于哪种类型:

1. 若以00结尾,则为字面量:判断l<=60(注意l+1!!!),若是则直接调用Print_ConstData输出;若不是则记录还有多少字节的说明部分,置state

2. 若以01结尾,则为回溯引用形式1:记录var_l和var_o高3位,置state

3. 若以10结尾,则为回溯引用形式2:记录var_l和剩余的说明部分,置state

else if(state == "finish") {
	if(Byte % 4 == 0) {
		ll l = Byte / 4 + 1;
		if(l <= 60) {
			Print_ConstData(l);
			s_length += l;
		}
		else {
			const_guide_length = l - 60;
			const_guide_length_i = 0;
			state = "const_guide";
		}
	}
	else if(Byte % 4 == 1) {
		var_l = Byte / 4 % 8 + 4;
		var_o = Byte / 32 * 256;
		state = "var_guide_1";
	}
	else {
		var_l = Byte / 4 + 1;
		var_guide_length = 2;
		var_guide_length_i = 0;
		state = "var_guide_2";
	}
}

主函数循环中state为const_guide的情况

补充const_l,若已经将说明部分读取完了则先l+1!!!再直接调用Print_ConstData输出,置state

else if(state == "const_guide") {
	const_l += Byte * pow(256, const_guide_length_i);
	if(++const_guide_length_i == const_guide_length) {
		Print_ConstData(++const_l);
		s_length += const_l;
		const_l = 0;
		state = "finish";
	}
}

主函数循环中state为var_guide_1的情况 

补充var_o,调用Print_VarData输出,置state

else if(state == "var_guide_1") {
	var_o += Byte;
	Print_VarData(var_o, var_l);
	var_o = var_l = 0;
	state = "finish";
}

主函数循环中state为var_guide_2的情况 

补充var_o,若已经将说明部分读取完了则调用Print_VarData输出,置state

else {
	var_o += Byte * pow(256, var_guide_length_i);
	if(++var_guide_length_i == var_guide_length) {
		Print_VarData(var_o, var_l);
		var_o = var_l = 0;
		state = "finish";
	}
}

完整代码

#include
using namespace std;
#define ll long long

vector output;
ll output_length = 0;

int CharToInt(char HighByte, char LowByte)
{
	int H = ('0'<=HighByte && HighByte<='9') ? HighByte-'0' : HighByte-'a'+10;
	int L = ('0'<=LowByte && LowByte<='9') ? LowByte-'0' : LowByte-'a'+10;
	return H * 16 + L;
}

void PrintInt(int x)
{
	int H = x / 16, L = x % 16;
	char HighByte = (0<=H && H<=9) ? H+'0' : H+'a'-10;
	char LowByte = (0<=L && L<=9) ? L+'0' : L+'a'-10;
	cout<>HighByte>>LowByte;
		int Byte = CharToInt(HighByte, LowByte);
		PrintInt(Byte);
		output.push_back(Byte);
	}
}

void Print_VarData(ll var_o, ll var_l)
{
	queue var_output;
	for(ll i=0; i>s;
	for(ll s_length=0; s_length>HighByte>>LowByte;		Byte = CharToInt(HighByte, LowByte);
		if(state == "guide") {
			if(Byte >= 128)
				data_length += (Byte-128) * pow(128, guide_length++);
			else {
				data_length += Byte * pow(128, guide_length++);
				state = "finish";
			}
		}
		else if(state == "finish") {
			if(Byte % 4 == 0) {
				ll l = Byte / 4 + 1;
				if(l <= 60) {
					Print_ConstData(l);
					s_length += l;
				}
				else {
					const_guide_length = l - 60;
					const_guide_length_i = 0;
					state = "const_guide";
				}
			}
			else if(Byte % 4 == 1) {
				var_l = Byte / 4 % 8 + 4;
				var_o = Byte / 32 * 256;
				state = "var_guide_1";
			}
			else {
				var_l = Byte / 4 + 1;
				var_guide_length = 2;
				var_guide_length_i = 0;
				state = "var_guide_2";
			}
		}
		else if(state == "const_guide") {
			const_l += Byte * pow(256, const_guide_length_i);
			if(++const_guide_length_i == const_guide_length) {
				Print_ConstData(++const_l);
				s_length += const_l;
				const_l = 0;
				state = "finish";
			}
		}
		else if(state == "var_guide_1") {
			var_o += Byte;
			Print_VarData(var_o, var_l);
			var_o = var_l = 0;
			state = "finish";
		}
		else {
			var_o += Byte * pow(256, var_guide_length_i);
			if(++var_guide_length_i == var_guide_length) {
				Print_VarData(var_o, var_l);
				var_o = var_l = 0;
				state = "finish";
			}
		}
	}
	return 0;
}
/*
81
8001240102030405
060708090af03c00
0102030405060708
090a0b0c0d0e0f01
0203040506070809
0a0b0c0d0e0f0102
030405060708090a
0b0c0d0e0f010203
0405060708090a0b
0c0d0e0fc603000d
78
*/

你可能感兴趣的:(c++,算法)