栈算法-将3[2[a]2[b]]变为aabbaabbaabb

208 阅读3分钟

将3[2[a]2[b]]变为aabbaabbaabb

  • 问题分析:

    • 关键点一、是 [ 符号之前数字,得想办法存下来。
    • 关键点二、这个数字对应的字符串。
    • 关键点三、字符串的重复一定得从里面向外边。
  • 从题目中给出的信息有四种类型,

    • 1.数字(决定字符的重复次数)
    • 2.字符[ 决定了数字的位置
    • 3.字符[和]中间的字符串
      1. 字符]决定了字符串结束的位置。
  • 技术点栈存储,因为从关键点三可以看出来,字符串的重复是从里面向外边走的。栈的特别是后进先出。用两个栈 stack1 和 stack2 来存储,一个用来存储数字,一个用来存储 字符串。


            思路:
                1. 需要对 str = 3[2[ama]2[b]] 字符串 字符串进行遍历,因为遍历时候的索引可能出现跳跃的情况
                所以用 while 循环来进行遍历。
                2. 从i = 0 开始遍历 str 字符。
                    i = 0: 检测出是数字,就把 3 放入stack1[3]
                    i = 1: 是字符 [ , 把一个空的字符 '' 放入 stack2 ['']
                    i = 2: 是字符 2 , 数字 2 放入到 stack1中, [3, 2]
                    i = 3: 是字符 [ , 把一个空的字符 '' 放入 stack2 ['', '']
                    i = 4: 是字符 a , 把字符 astack2的最后一个位置 ['', '', 'a']
                    i = 5: 是字符 m , 把字符 mstack2的最后一个位置 ['', '', 'm']
                    i = 6: 是字符 a , 把字符 astack2的最后一个位置 ['', '', 'ama']
                    i = 7: 是字符 ] , 把 stack1的最后一个数字 2 出栈,
                                        stack2的最后一个字符串 'ama'出栈,
                                        然后出栈字符重复 对应的个数及 'amaama',把这个字符
                                        放在 stack2的最后一位,及 stack2 = ['', 'amaama']
                    i = 8: 是数字 2 , 把 2 放入到 stack1[3, 2]
                    i = 9: 是字符 [ , 把 空字符 '', 放入到栈 stack2中 ['', 'amaama', '']
                    i = 10:是字符 b , 把字符 bstack2的最后一个位置 ['', 'amaama', 'b']
                    i = 11:是字符 ] , 把stack1中的数字 2 出栈,stack2中的 'b' 出栈,组成 'bb'
                                     然后再放入stack2的最后一个位置,['', 'amaamabb']
                    i = 12:是字符 ] , 把 stack1栈顶的数据 3 弹出,把 stack2的栈顶字符 'amaamabb' 
                                    弹出,组成 'amaamabbamaamabbamaamabb' , 然后把字符放入
                                    stack2的最后一位 ['amaamabbamaamabbamaamabb']

代码

        // let str = '30[2[ama]3[b]]';
        let str = '2[2[abc]1[z]]';
        let regNumExp = /^(\d+)\[/;
        let regStrExp = /^(\w+)\]/;

        let stack1 = [], // 存放数字
            stack2 = []; // 存放字符
        let i = 0;

        // 用来正则匹配数字
        // str = 'asdfasdf'
        // console.log(str.match(regNumExp))

        // str = 'ama]3[b]]';
        // console.log(str.match(regStrExp))
        
        // debugger
        while(i < str.length) {

            // 先判断从开始到字符 是 数字+[ 这种情况 用正则判断
            let restStr = str.slice(i);
            console.log(i, '剩余的字符 = ', restStr)
            if(restStr.match(regNumExp)) {
                let num = restStr.match(regNumExp)[1];

                // console.log('要进入 stack1 中 = ', num);
                stack1.push(num);
                i += num.length;
            } else if(str[i] === '[') {

                // console.log(i , '这个时候要给栈 stack2中添加 空的字符')
                stack2.push('');
                i++;
            } else if(restStr.match(regStrExp)) {

                let s = restStr.match(regStrExp)[1];
                stack2.push(s);
                console.log('-- 匹配到的字符 = ', s);

                i += s.length;
            } else if(str[i] === ']') {
                // console.log('需要计算的数字le ', JSON.stringify(stack1))
                // console.log('需要计算le ', JSON.stringify(stack2))
                
                let num = parseInt(stack1.pop());
                
                let s = stack2.pop();
                
                let countS = (stack2[stack2.length - 1] + s).repeat(num);
                console.log('计算额 = ', num,  s)
                stack2[stack2.length - 1] = countS;
                
                console.log('需要计算 后 ', JSON.stringify(stack2))

                i++;
            } else {
                i++;
            }
        }

        console.log(stack1)
        console.log(stack2)