JavaScript栈思想的应用(实现智能重复函数)

需求:实现一个“智能重复”函数,实现下面字符串的转换
将 2[abc] 转成 abcabc 将 2[1[a]2[b]] 转成 abbabb 将 2[1[a]2[3[b]4[c]]] 转成 abbbccccbbbccccabbbccccbbbcccc

思路及原理 原理:使用“栈”思想来实现,在JavaScript中实现“栈”的最好数据结构是数组
思路:
  • 1、定义两个栈(数组),栈1(stack1)、栈2(stack2),stack1用来存储数字,stack2用来存储字符串
  • 2、定义一个指针(索引),默认从0开始
  • 3、循环这个字符串,指针一直向后移动,直到指针等于字符串长度减1
  • 【JavaScript栈思想的应用(实现智能重复函数)】4、获取当前指针指向的这个字符,然后进行判断
    • a)、如果是数字
      stack1中推入这个数字,stack2中推入一个空字符,指针继续向后移动
    • b)、如果是“[”
      什么都不做,指针继续向后移动
    • c)、如果是字符串
      将stack2栈顶项修改为该字符串,指针继续向后移动
    • d)、如果是“]”
      • stack1栈顶数字弹出,得到需要重复的次数,起个名字叫:repeatCount
      • stack2栈顶空字符串弹出
      • 将stack2栈顶项修改为:tack2栈顶项 + 重复repeatCount后的字符串
      • 指针继续向后移动
用一涨动图来演示
JavaScript栈思想的应用(实现智能重复函数)
文章图片

代码实现
function smartRepeat(template){ let stack1 = []; // 存放数字 let stack2 = []; // 存放字符串 let index = 0; // 指针 let remaining = template; // 剩余部分// 这里index要小于template.length - 1,当遇到最后一个“]”的时候就不需要再出栈了,因为此时数组长度为1了,此时出栈再获取数组最后一项的值就会变成undefined while (index < template.length - 1){ if(/(^\d+)\[/.test(remaining)){ // 如果是数字。因为xxx]里的xxx数字后面一定是“]”,如果不加上“]”,那么在匹配的时候很可能会将要循环的字符串误匹配为数字 let countStr = RegExp.$1; // RegExp.$1获取的就是/(^\d+)/这个正则中括号分组中匹配到的内容 let len = countStr.length; stack1.push(countStr * 1); stack2.push(''); index += len; remaining = remaining.substr(len); console.log('推入数字:', countStr * 1); console.log('stack1', stack1); console.log('stack2', stack2); } else if(remaining.charAt(0) == '['){ // 如果是“[” index++; remaining = remaining.substr(1); console.log('推入空字符串:'); console.log('stack1', stack1); console.log('stack2', stack2); } else if(/^(\w+)\]/.test(remaining)) { // 如果是字符串。因为[xxx]里的xxx可以是数字、字母或数字字母的组合,并且他们后面一定是“]”,所以这里的正则需要加上“]” let chats = RegExp.$1; let stack2LastStr = stack2[stack2.length - 1]; stack2[stack2.length - 1] = stack2LastStr + chats; index += chats.length; remaining = remaining.substr(chats.length); console.log('推入字符串:', chats); console.log('stack1', stack1); console.log('stack2', stack2); } else if(remaining.charAt(0) == ']') { // 如果是“]”,需出栈 let repeatCount = stack1.pop(); let needRepeatStr = stack2.pop(); console.log('出栈,两个栈顶:', repeatCount, needRepeatStr); let resultStr = needRepeatStr.repeat(repeatCount); // 结果字符串 let stack2LastStr = stack2[stack2.length - 1]; stack2[stack2.length - 1] = stack2LastStr + resultStr; index++; remaining = remaining.substr(1); console.log('出栈,结果字符串:', resultStr, stack2LastStr); console.log('stack1', stack1); console.log('stack2', stack2); } else { index++; remaining = remaining.substr(1); } }console.log('循环完成--------------', index); console.log('stack1', stack1); console.log('stack2', stack2); let repeatCount = stack1.pop(); let needRepeatStr = stack2.pop(); let resultStr = needRepeatStr.repeat(repeatCount); // 结果字符串 console.log('最终结果字符串:', resultStr); return resultStr; }// 输出结果:abcabc smartRepeat('2[abc]'); // 输出结果:abbabb smartRepeat('2[1[a]2[b]]'); // 输出结果:abbbccccbbbccccabbbccccbbbcccc smartRepeat('2[1[a]2[3[b]4[c]]]'); // 输出结果:1ab2b2b2ccccb2b2b2cccc1ab2b2b2ccccb2b2b2cccc smartRepeat('2[1[1a]2[3[b2]4[c]]]');

    推荐阅读