共计 2605 个字符,预计需要花费 7 分钟才能阅读完成。
需要:实现一个“智能反复”函数,实现上面字符串的转换
将 2[abc] 转成 abcabc
将 2[1[a]2[b]] 转成 abbabb
将 2[1[a]2[3[b]4]] 转成 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 后的字符串
- 指针持续向后挪动
- a)、
用一涨动图来演示
代码实现
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]]');
// 输入后果:1ab2b2b2ccccb2b2b2cccc1ab2b2b2ccccb2b2b2cccc
smartRepeat('2[1[1a]2[3[b2]4]]');
正文完