首页 > 其他分享 >LeetCode 题解 394. 字符串解码

LeetCode 题解 394. 字符串解码

时间:2022-11-10 00:15:03浏览次数:46  
标签:int 题解 LeetCode char num 394 alpha stack ptr

题目描述

给定一个经过编码的字符串,返回它解码后的字符串。

编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。

你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。

此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a2[4] 的输入。

样例

样例输入 #1

s = "3[a]2[bc]"

样例输出 #1

"aaabcbc"

样例输入 #2

s = "3[a2[c]]"

样例输出 #2

"accaccacc"

样例输入 #3

s = "2[abc]3[cd]ef"

样例输出 #3

"abcabccdcdcdef"

样例输入 #4

s = "abc3[cd]xyz"

样例输出 #4

"abccdcdcdxyz"

提示

  • 1 <= s.length <= 30
  • s 由小写英文字母、数字和方括号 '[]' 组成
  • s 保证是一个 有效 的输入。
  • s 中所有整数的取值范围为 [1, 300]

题解

思路一:递归

1.将字符串拆解成倍数和字符

2.将字符复制

3.字符内若任有'[]',则递归重复上述操作

- 注意:函数返回的字符串要经过动态分配

C代码

struct take_apart {	 //定义结构体,方便函数decode_square_brackets(char* s)同时返回拆解后的倍数和字符
	int number;	 //用于存储方括号前的倍数
	char string[35]; //用于存储方括号内的字符串
};
struct take_apart decode_square_brackets(char* s) //输入3[a2[c]],拆解成3 & a[2[c]]
{
	struct take_apart ret;
	sscanf(s, "%d[%s", &ret.number, ret.string); //拆解
	ret.string[strlen(ret.string) - 1] = '\0';//把最后的“]”换成空字符
	return ret;
}
char* decode(char s[], int begin, int end) {
	int ptr_ret = 0;//返回数组的操作位
	char* ret = (char*)malloc(sizeof(char) * 1800); //用于存储解码后的字符串
	while (begin <= end)//遍历全数组
	{
		if (isdigit(s[begin])) //如果出现数字,如"3[a2[c]]"
		{
			char square_brackets[35]; //需要拆解的字符串
			int ptr_square_brackets = 0;
			int count_square_brackets = 0; //标记左方括号的出现次数,以保证对应的左右方括号一一配对
			while (1)  //将s[]中需要拆解的字符串拷贝到square_brackets[]中,便于用sscanf()处理
			{
				if (s[begin] == '[')
					count_square_brackets++; //出现左方括号,累加
				if (s[begin] == ']')
					count_square_brackets--;   //出现右方括号,递减
				square_brackets[ptr_square_brackets++] = s[begin++];   //将需要拆解字符串拷贝到square_brackets[]数组中
				if (count_square_brackets == 0 && square_brackets[ptr_square_brackets - 1] == ']') //如果左右方括号一一对应,并且读取到']'时
					break;   //拷贝结束,跳出循环
			}
			square_brackets[ptr_square_brackets] = '\0';//在字符串末尾添加空字符
			struct take_apart ret_square_brackets = decode_square_brackets(square_brackets);//将 倍数 与 方括号内的字符串 拆解开,分别存储
			int num = ret_square_brackets.number;//倍数
			char next_ret[300];//方括号内的字符串
			sprintf(next_ret, "%s", decode(ret_square_brackets.string, 0, strlen(ret_square_brackets.string) - 1)); //将方括号内的字符串继续解码,实现递归
			int len = strlen(next_ret);
			for (int i = 0; i < num; i++) //将next_ret[]中的字符串复制num次
			{
				for (int j = 0; j < len; j++)
					ret[ptr_ret++] = next_ret[j];
			}
		}
		while (isalpha(s[begin])) //处理方括号外的单独字母
		{
			ret[ptr_ret++] = s[begin++];
		}
	}
	ret[ptr_ret] = '\0'; //补足空字符
	return ret;
}
char* decodeString(char* s) {
	return decode(s, 0, strlen(s) - 1);
}

思路二:数组栈模拟

1.像开花一样将方括号内的字符串从内到外层层展开

2.用ptr_alpha标记处理到的位置,不用担心展开时出现“覆盖到相邻位置”的情况

C代码

char* decodeString(char* s) {//拆解字符串,例如:"3[a]2[bc]"
	char* stack_num = (char*)malloc(sizeof(char) * 20);//用于存储数字位,如:"3[2["
	char* stack_alpha = (char*)malloc(sizeof(char) * 1800);//用于存储字符位,如:"[a[bc"
	int len = strlen(s);
	int ptr_num = 0, ptr_alpha = 0;
	for (int i = 0; i < len; i++) {
		char temp = s[i];//拷贝s[i]至temp,减少数组寻址时间
		if (temp == '[') {//对于'[',同时存储
			stack_num[ptr_num++] = '[';
			stack_alpha[ptr_alpha++] = '[';
		}
		else if (isdigit(temp)) {//将数字存放至stack_num[]
			stack_num[ptr_num++] = temp;
		}
		else if (isalpha(temp)) {//将字母存放至stack_alpha[]
			stack_alpha[ptr_alpha++] = temp;
		}
		else if (temp == ']') {//读取到']',开始处理
			int number = 0;
			int ten_times = 1;
			ptr_num = ptr_num - 2;
			while (ptr_num >= 0 && stack_num[ptr_num] != '[') {//将倍数转换为十进制,并存放到number
				number += (stack_num[ptr_num] - '0') * ten_times;
				ten_times *= 10;
				ptr_num--;
			}
			ptr_num++;//将ptr_num重新对准'['位,便于处理
			ptr_alpha--;//将ptr_alpha也重新对准'['位,便于处理
			char copy[300];//存放用于翻倍的字符串
			int ptr_copy = 300;
			while (stack_alpha[ptr_alpha] != '[') {
				copy[--ptr_copy] = stack_alpha[ptr_alpha--];//逆序存储,便于正序输出
			}
			while (number--) {//将copy[]中的字符串,翻倍number次,并存放到stack_alpha中
				for (int j = ptr_copy; j < 300; j++) {
					stack_alpha[ptr_alpha++] = copy[j];
				}
			}
		}
	}
	stack_alpha[ptr_alpha] = '\0';
	return stack_alpha;
}

标签:int,题解,LeetCode,char,num,394,alpha,stack,ptr
From: https://www.cnblogs.com/fjnhyzCYL/p/16875663.html

相关文章

  • 题解 LGP7071 【 [CSP-J2020] 优秀的拆分】
    postedon2020-11-1217:22:31|under题解|source本题正解是二进制or位运算理解题目P7071优秀的拆分(民间数据)题目链接:https://www.luogu.com.cn/problem......
  • 题解 LGP7909 【[CSP-J 2021] 分糖果】
    postedon2021-10-2322:52:47|under题解|source分类讨论。一句话题意:求\(\max\limits_{i=l}^{r}\{i\bmodn\}\)首先画个数轴,按除以\(n\)向下取整的商把这些整......
  • 题解 LGP8819【[CSP-S 2022] 星战】
    postedon2022-10-3011:39:14|under题解|sourceproblem一个\(n\)个点\(m\)条边的有向图,\(q\)次操作:删除一条边,保证存在;增加一条边,保证不存在;删除一个点......
  • 题解 LGP8817【[CSP-S 2022] 假期计划】
    postedon2022-10-2923:32:15|under题解|sourceproblem\(n\)个点\(m\)条边的无向无权图,令\(to(i,j)=[\operatorname{dist}(i,j)\leqk+1]\),点带权\(a_i\),求:......
  • 题解 LGP7343【[DSOI 2021] 电子跃迁】
    postedon2021-02-0718:12:18|under题解|source题意简述给出一长为\(n\)的数列\(a\)和一长为\(m\)的数列\(b\),你可以交换\((a_i,a_{i+1})\)的位置,但不能......
  • 题解 AGC033D【Complexity】
    problem定义一个0/1矩阵\(B\)的复杂度为:若\(B\)只由一种数字组成,其复杂度为\(0\)。否则,用一条平行于矩阵\(B\)任意一边的直线将\(B\)划分为两部分,则复杂度......
  • LeetCode刷题记录.Day10
    四数相加II题目链接454.四数相加II-力扣(LeetCode)classSolution{public:intfourSumCount(vector<int>&nums1,vector<int>&nums2,vector<int>&nums3,v......
  • CF1056G Take Metro 题解
    *2900的题,评到黑题是因为std做法要用可持久化平衡树,然而有一种更简洁的做法。注意到\(t\)很大,然后每一步只和\(t\bmodn\)的大小有关系,因此你想先求出\(t=n\)时......
  • LuoguP1586 题解
    也可以在LuoguP1586(tencentcs.com)获得更好的阅读体验。Luogu_P1586题解一道比较简单的题目,看到求种类数,考虑DP。设\(f_{i,j}\)表示第\(i\)个数划分为\(j\)......
  • 11.7 模拟赛题解
    幸终简要题意给定一棵树,\(1\)号节点为根节点,记\(d_i\)为\(i\)号节点到根节点最短路径所经过的边数,\(mxd=max_{i=1}^nd_i\)。现在要把这棵树剖分成若干条链,每条链链......