7

There are dreams and dry goods. search 160bd689203121 [Great Move to the World] Follow this brushing wit who is still doing dishes in the early morning.

This article GitHub https://github.com/qq449245884/xiaozhi has been included, the first-line interview complete test site, information and my series of articles.

Before explaining this problem, let's look at the next data structure: stack , because we need to use a stack to solve this problem.

Stack

Stack (Stack), also known as the stack, which is a linear form of operation is limited, only can insert and delete operations at the end of the table . This end is called the top of the stack, while the other end is called the bottom of the stack.

Inserting a new element into a stack is also called pushing, pushing or pushing on the stack; deleting an element from a stack is also called making a stack or unstacking.

Last-in-first-out (LIFO) features: elements in the stack, the most advanced stack must be the last out of the stack, the last in the stack must be out of the stack first.

In JavaScript, the stack can be simulated with an array. It is necessary to restrict the use of push() and pop() , but not unshift() and shift() . That is, the end of the array is the top of the stack.

Of course, object-oriented methods can be used to encapsulate the stack better.

image.png

Interview questions

This is an interview question from Toutiao and Didi. The topic is like this:

Try to write the "smart Repeat" smartRepeat function to achieve:

  • abcabcabc 3[abc] to 060bd689203336
  • aabbaabbaabb 3[2[a]2[b]] to 060bd689203355
  • abbbcccddddcccddddabbbcccddddcccdddd 2[1[a]3[b]2[3[c]4[d]]] to 060bd68920337f

Don't worry about the situation where the input string is illegal, such as:

  • 2[a3[b]] is wrong, you should add a 1, that is, 2[1[a]3[b]]
  • [abc] is wrong, you should add a 1, that is, 1[abc]

When you see this problem, you should think of doing it in a recursive way. In fact, it is more difficult to use recursion for this problem. It can be done, but the stack method is much simpler than the stack.

beginner's pit: stack problem is very similar to recursion, this kind of problem gives people the feeling that recursion is used to solve the problem. I started writing with confidence, but found that recursion couldn't come out. At this point, it should be thought of, not to use recursion, but to use the stack.

We can use two stacks to solve this problem. The first stack stores numbers and the second stack stores strings.

image.png

At this time, we can find that our pointer only needs to be traversed once. What do you think?

The rule is this: traverse to the number and push the number onto the stack

image.png

Then continue to traverse, and then traverse to square brackets, or to traverse to numbers and square brackets, then we put another stack into an empty string '' .

image.png

Then move down, and when you encounter 3, it is also pushed onto the stack:

image.png

Then move down, encounter square brackets, press an empty string ''

image.png

Then move down and encounter the letter a , then what is the rule for encountering a letter, as shown in the figure:

image.png

Then move down and encounter ] . Note that it is a very important time when traversing to the closing curly brace. What about this rule, as shown below:

image.png

Isn’t it a bit unintelligible, so let’s run again

Then move down to meet 4[ , and press the number 4 and the empty string into:

image.png

Then move down to 1[ , and press the number 1 and the empty string into:

image.png

Then move down to meet b , press:

image.png

Then move down, encounter the terminator ] , and pop up 1 and'b' respectively. At this time, after repeating the'b' again, splice it to the second stack top element

image.png

Then move down, encounter 2, the same operation:

image.png

Then move down to encounter c and write directly:

image.png

Then move down, encounter the terminator ] , and pop 2 and'c' respectively. At this time, repeat the'c' twice and splice it to the second stack top element

image.png

Then down, face penultimate terminator ] , respectively, and the 4 'bccc', the pop-up, in this case the 'bccc' repeated four four times spliced to the second top element

image.png

Then down, by encountering the last terminator ] , respectively, and the 2 'aaabccbccbccbcc', pop up and repeated in the 'aaabccbccbccbcc' twice , a case would not have to fight to an element, as it has a The last one:

image.png

Is this answer our last answer? It’s amazing~

At this time, we are following the above process to demonstrate this problem:

2[1[a]3[b]2[3[c]4[d]]] becomes abbbcccddddcccddddabbbcccddddcccdddd .

Code

Create index.js and enter the following:

// 试编写“智能重复”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);

~End, I’m Xiaozhi, and I’m going to use Niuke.com, see you in the next issue~

possible bugs after code deployment cannot be known in real time. In order to solve these bugs afterwards, a lot of time was spent on log debugging. By the way, I would like to recommend a useful BUG monitoring tool Fundebug .

communicate with

There are dreams and dry goods. search 160bd6892039ae [Great Move to the World] Follow this brushing wit who is still doing dishes in the early morning.

This article GitHub https://github.com/qq449245884/xiaozhi has been included, the first-line factory interview complete test sites, materials and my series of articles.


王大冶
68.1k 声望105k 粉丝