关于栈: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
  • 4、获取以后指针指向的这个字符,而后进行判断

    • a)、如果是数字
      stack1中推入这个数字,stack2中推入一个空字符,指针持续向后挪动
    • b)、如果是“[”
      什么都不做,指针持续向后挪动
    • c)、如果是字符串
      将stack2栈顶项批改为该字符串,指针持续向后挪动
    • d)、如果是“]”

      • stack1栈顶数字弹出,失去须要反复的次数,起个名字叫:repeatCount
      • stack2栈顶空字符串弹出
      • 将stack2栈顶项批改为:tack2栈顶项 + 反复repeatCount后的字符串
      • 指针持续向后挪动

用一涨动图来演示

代码实现

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]]]');

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理