利用“栈”和指针的方式计算

试编写“智能重复”smartRepeat函数,实现:

3[abc] 变为 abc abc abc
3[2[a]2[b]] 变为 aabb aabb aabb
2[1[a]3[b]2[3[c]4[d]]] 变为 abbbcccddddcccdddd abbbcccddddcccdddd
不用考虑输入字符串是非法的情况,比如:
2[a3[b]] 是错误的,应该补一个 1 ,即 2[1[a]3[b]]
[abc] 是错误的,应该补一个 1 ,即 1[abcjietu 

解题思路:

定义两个数组,一个存放数组,一个存放字符串

遍历每一个字符
如果这个字符是数字,那么就把数字压栈,把空字符串压栈
如果这个字符是字母,那么此时就把栈顶这项改为这个字母
如果这个字符是 ] ,那么就将数字弹栈,就把字符串栈的栈顶
的元素重复刚刚的这个次数,弹栈,拼接到新栈顶上

解题前需要储备的基础知识:

<script>
'dnjdsbb254763'.replace(/\d/g,'')
//'dnjdsbb'

'dnjdsbb254763'.search(/\d/)
//7

'dnjdsbb254763'.match(/\d/g)
// ['2', '5', '4', '7', '6', '3']

'dnjdsbb254763'.match(/(\d)/g)
// ['2', '5', '4', '7', '6', '3']

'234[dnj]'.match(/^\d+\[/)
//['234[', index: 0, input: '234[dnj]', groups: undefined]

'234[dnj]'.match(/^(\d+)\[/) //() 表示捕获 捕获的结果出现在了下标为1项
// ['234[', '234', index: 0, input: '234[dnj]', groups: undefined]

'abcdefg'.substring(3) //只有一个参数时截取的时,当前下标(包含当前项)
// 'defg' 

'abc'.repeat(3) //当前字符串重复 3遍
//'abcabcabc' 

</script>

<script>
        // 试编写“智能重复”smartRepeat函数,实现:
        // 将3[abc]变为abcabcabc
        // 将3[2[a]2[b]]变为aabbaabbaabb  
        // 将2[1[a]3[b]2[3[c]4[d]]]变为abbbcccddddcccddddabbbcccddddcccdddd

        function smartRepeat(templateStr) {
            // 指针
            var index = 0;
            // 栈1,存放数字
            var stack1 = [];
            // 栈2,存放临时字符串
            var stack2 = [];
            // 剩余部分
            var rest = templateStr;

            while (index < templateStr.length - 1) {
                // 剩余部分
                rest = templateStr.substring(index);

                // 看当前剩余部分是不是以数字和[开头
                if (/^\d+\[/.test(rest)) {
                    // 得到这个数字
                    let times = Number(rest.match(/^(\d+)\[/)[1]);
                    // 就把数字压栈,把空字符串压栈
                    stack1.push(times);
                    stack2.push('');
                    // 让指针后移,times这个数字是多少位就后移多少位加1位。
                    // 为什么要加1呢?加的1位是[。
                    index += times.toString().length + 1;
                } else if (/^\w+\]/.test(rest)) {
                    // 如果这个字符是字母,那么此时就把栈顶这项改为这个字母
                    let word = rest.match(/^(\w+)\]/)[1];
                    stack2[stack2.length - 1] = word;
                    // 让指针后移,word这个词语是多少位就后移多少位
                    index += word.length;
                } else if (rest[0] == ']') {
                    // 如果这个字符是],那么就①将stack1弹栈,②stack2弹栈,③把字符串栈的新栈顶的元素重复刚刚弹出的那个字符串指定次数拼接到新栈顶上。
                    let times = stack1.pop();
                    let word = stack2.pop();
                    // repeat是ES6的方法,比如'a'.repeat(3)得到'aaa'
                    stack2[stack2.length - 1] += word.repeat(times);
                    index++;
                }

                console.log(index, stack1, stack2);
            }

            // while结束之后,stack1和stack2中肯定还剩余1项。返回栈2中剩下的这一项,重复栈1中剩下的这1项次数,组成的这个字符串。如果剩的个数不对,那就是用户的问题,方括号没有闭合。
            return stack2[0].repeat(stack1[0]);
        }

        var result = smartRepeat('3[2[3[a]1[b]]4[d]]');
        console.log(result);
    </script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值