#include <iostream> #include <string> #include<ctype.h> using namespace std; /* 思路: 此题可以将原字符串看成:数字和括号内的字符串,数字和单个字母 的这两个组合,就是重复输出括号内的字符串和单个字母的任务。 所以我们应该先将前面的数字字符串处理成数字,对于没有数字的情况,我们默认为1。 不难想到括号内的字符串我们可以用递归来实现,递归外应该用循环来遍历整个字符串,遇到单个字母我们直接输出; 其中因为只重复输出括号内的内容,我们应添加一个循环条件:非右括号才可以; 所以当我们遍历完整个括号内的字符串后,应该把右括号后一个位置的索引值赋给循环迭代的索引值, 说明我们括号内的字符串已经输出完毕,应当处理后面的字符串了。 */ string str; int dfs(int idx){ //循环内套递归,实质上仅遍历一次 char ch; int cnt; for (ch = str[idx++]; ch != ‘)‘ && idx < str.size(); ch = str[idx++]){ //因只单次处理括号的内容,所以设置右括号为跳出条件 for (cnt = 0; isdigit(ch); ch = str[idx++]) cnt = cnt * 10 + ch - ‘0‘; // 是数字的情况 if (!cnt) cnt = 1; // //数字后不是左括号就是字母 if (ch == ‘(‘){ // 是左括号的情况,就递归输出cnt次的括号里的内容(哪怕前面无数字,cnt也为1) int tmp; while (cnt--) tmp = dfs(idx); idx = tmp; //匹配的右括号后面一个位置 } else while (cnt--) cout << ch; //是字母的情况,就输出cnt次的字母(哪怕前面无数字,cnt也为1) } if (ch == ‘)‘) return idx; } int main(){ int t; cin >> t; while (t--){ cin >> str; dfs(0); cout << endl; } system("pause"); return 0;
用递归的思想展开字符串:
1.for (ch = str[idx++]; ch != ‘)‘ && idx < str.size(); ch = str[idx++])
学习了一种新的使用for循环的形式,idx++先赋值再加1,括号里第1项和第3项使得字符一直向后遍历到结束。
2.if (!cnt) cnt = 1;
这种用法的意思是:如果cnt为0,则让cnt=1。
3.while (cnt--) cout << ch;
这种用法表示cnt自减到0,跳出循环。for(int n=3;n>0;n--)跟int n=3;while(n--){n>0}一样。
原文:https://www.cnblogs.com/hl220284/p/10507784.html