zoukankan      html  css  js  c++  java
  • 【2】展开字符串(栈、递归)

    #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;
    View Code

    问题描述:在纺织CAD系统开发过程中,经常会遇到纱线排列的问题。
    该问题的描述是这样的:常用纱线的品种一般不会超过25种,所以分别可以用小写字母表示不同的纱线,例如:abc表示三根纱线的排列;重复可以用数字和括号表示,例如:2(abc)表示abcabc;1(a)=1a表示a;2ab表示aab;如果括号前面没有表示重复的数字出现,则就可认为是1被省略了,如:cd(abc)=cd1(abc)=cdabc;这种表示方法非常简单紧凑,也易于理解;但是计算机却不能理解。为了使计算机接受,就必须将简单紧凑的表达方式展开。某ACM队接受了此项任务。现在你就是该ACM队的一员,请你把这个程序编写完成。
    已知条件:输入的简单紧凑表达方式的长度不超过250个字符;括号前表示重复的数不超过1000;不会出现除了数字、括号、小写字母以外的任何其他字符;不会出现括号不配对等错误的情况(错误处理已由ACM其他队员完成了)。

    思路:利用栈对括号进行存取

    用递归的思想展开字符串:

    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(注意:是自减到0!),跳出循环。for(int n=3;n>0;n--)等价于 int n=3;while(n--){n>0}。

  • 相关阅读:
    Scala中的构造器和高阶函数
    Scala中的元组
    Scala中的Map
    Scala中的If判断&While&For循环
    [改善Java代码]asList方法产生的List对象不可更改
    [改善Java代码]避开基本类型数组转换列表陷阱
    [改善Java代码]枚举和注解结合使用威力更大
    [改善Java代码]枚举项的数量限制在64个以内
    [改善Java代码]用枚举实现工厂方法模式更简洁
    [改善Java代码]在switch的default代码块中增加AssertionError错误
  • 原文地址:https://www.cnblogs.com/hl220284/p/10507784.html
Copyright © 2011-2022 走看看