需要:实现一个“智能反复”函数,实现上面字符串的转换 将 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、循环这个字符串,指针始终向后挪动,直到指针等于字符串长度减14、获取以后指针指向的这个字符,而后进行判断
a)、如果是数字 stack1中推入这个数字,stack2中推入一个空字符,指针持续向后挪动b)、如果是“[” 什么都不做,指针持续向后挪动c)、如果是字符串将stack2栈顶项批改为该字符串,指针持续向后挪动d)、如果是“]”
stack1栈顶数字弹出,失去须要反复的次数,起个名字叫:repeatCountstack2栈顶空字符串弹出将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;}// 输入后果:abcabcsmartRepeat('2[abc]');// 输入后果:abbabbsmartRepeat('2[1[a]2[b]]');// 输入后果:abbbccccbbbccccabbbccccbbbccccsmartRepeat('2[1[a]2[3[b]4[c]]]');// 输入后果:1ab2b2b2ccccb2b2b2cccc1ab2b2b2ccccb2b2b2ccccsmartRepeat('2[1[1a]2[3[b2]4[c]]]');