题目描述
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string]
,表示其中方括号内部的 encoded_string
正好重复 k
次。注意 k
保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k
,例如不会出现像 3a
或 2[4]
的输入。
样例
样例输入 #1
样例输出 #1
样例输入 #2
样例输出 #2
样例输入 #3
样例输出 #3
样例输入 #4
样例输出 #4
提示
- 1 <= s.length <= 30
- s 由小写英文字母、数字和方括号 '[]' 组成
- s 保证是一个 有效 的输入。
- s 中所有整数的取值范围为
[1, 300]
题解
思路一:递归
1.将字符串拆解成倍数和字符
2.按照倍数将字符复制n次
3.若拆解后的字符内还有下一级的'[]',则递归重复上述操作
- 注意:函数返回的字符串要经过malloc()动态分配
C代码
| #define MOD 1000000007 |
| int countGoodNumbers(long long n) { |
| int mark = n % 2; |
| long long ans = 1; |
| while (n - pow(10, 14) > 0) { |
| n -= pow(10, 14); |
| ans = (ans * 918742959) % MOD; |
| } |
| while (n - pow(10, 13) > 0) { |
| n -= pow(10, 13); |
| ans = (ans * 567839794) % MOD; |
| } |
| while (n - pow(10, 12) > 0) { |
| n -= pow(10, 12); |
| ans = (ans * 857412984) % MOD; |
| } |
| while (n - pow(10, 11) > 0) { |
| n -= pow(10, 11); |
| ans = (ans * 454060842) % MOD; |
| } |
| while (n - pow(10, 10) > 0) { |
| n -= pow(10, 10); |
| ans = (ans * 176203868) % MOD; |
| } |
| while (n - pow(10, 9) > 0) { |
| n -= pow(10, 9); |
| ans = (ans * 142875001) % MOD; |
| } |
| while (n - pow(10, 8) > 0) { |
| n -= pow(10, 8); |
| ans = (ans * 468083689) % MOD; |
| } |
| while (n - pow(10, 7) > 0) { |
| n -= pow(10, 7); |
| ans = (ans * 924188482) % MOD; |
| } |
| while (n - pow(10, 6) > 0) { |
| n -= pow(10, 6); |
| ans = (ans * 171395901) % MOD; |
| } |
| while (n - pow(10, 5) > 0) { |
| n -= pow(10, 5); |
| ans = (ans * 86331955) % MOD; |
| } |
| while (n - pow(10, 4) > 0) { |
| n -= pow(10, 4); |
| ans = (ans * 325891746) % MOD; |
| } |
| while (n - pow(10, 3) > 0) { |
| n -= pow(10, 3); |
| ans = (ans * 36020987) % MOD; |
| } |
| while (n - pow(10, 2) > 0) { |
| n -= pow(10, 2); |
| ans = (ans * 564490093) % MOD; |
| } |
| while (n - pow(10, 1) > 0) { |
| n -= pow(10, 1); |
| ans = (ans * 3200000) % MOD; |
| } |
| while ((n -= 2) >= 0) { |
| ans *= 20; |
| ans %= MOD; |
| } |
| if (mark) |
| return (ans * 5) % MOD; |
| return ans; |
| }struct take_apart { |
| int number; |
| char string[35]; |
| }; |
| struct take_apart decode_square_brackets(char* s) |
| { |
| 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])) |
| { |
| char square_brackets[35]; |
| int ptr_square_brackets = 0; |
| int count_square_brackets = 0; |
| while (1) |
| { |
| if (s[begin] == '[') |
| count_square_brackets++; |
| if (s[begin] == ']') |
| count_square_brackets--; |
| square_brackets[ptr_square_brackets++] = s[begin++]; |
| 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++) |
| { |
| 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) { |
| char* stack_num = (char*)malloc(sizeof(char) * 20); |
| char* stack_alpha = (char*)malloc(sizeof(char) * 1800); |
| int len = strlen(s); |
| int ptr_num = 0, ptr_alpha = 0; |
| for (int i = 0; i < len; i++) { |
| char temp = s[i]; |
| if (temp == '[') { |
| stack_num[ptr_num++] = '['; |
| stack_alpha[ptr_alpha++] = '['; |
| } |
| else if (isdigit(temp)) { |
| stack_num[ptr_num++] = temp; |
| } |
| else if (isalpha(temp)) { |
| 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 += (stack_num[ptr_num] - '0') * ten_times; |
| ten_times *= 10; |
| ptr_num--; |
| } |
| ptr_num++; |
| ptr_alpha--; |
| char copy[300]; |
| int ptr_copy = 300; |
| while (stack_alpha[ptr_alpha] != '[') { |
| copy[--ptr_copy] = stack_alpha[ptr_alpha--]; |
| } |
| while (number--) { |
| for (int j = ptr_copy; j < 300; j++) { |
| stack_alpha[ptr_alpha++] = copy[j]; |
| } |
| } |
| } |
| } |
| stack_alpha[ptr_alpha] = '\0'; |
| return stack_alpha; |
| } |
测试函数
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <ctype.h> |
| |
| int main() { |
| char s[] = "2[a2[c]]"; |
| printf("%s\n", decodeString(s)); |
| system("pause"); |
| return 0; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本