题目描述
给出一个字符串,其中有这样一个特殊情况[number|string]
,其中number
表示重复的字数,string
表示需要重复的字符串
示例:
输入:a[2|bc]d
输出:abcbcd
解题思路
首先考虑到的是,肯定不会通过分析每个字符去执行响应的操作,那样就把问题复杂化了,有经验的开发者首先就会想到正则来处理这种情况,即用replace()
方法来处理
最简单的情况
function deStr(str) {
let reg = /\[(\d+)\|(\w+)\]/g;
return str.replace(reg, function(match, repCount, matchedStr) {
return matchedStr.repeat(repCount);
})
}
这个方案能够处理一层模板的情况,但是匹配的字符串里面有嵌套呢,如[2|a[3|b]]
,显然这样的方案就不合适了,需要仅需改进
处理嵌套模板
function deStr(str) {
let reg = /\[(\d+)\|(.+)\]/g;
if (!reg.test(str)) {
return str;
}
return str.replace(reg, function(match, repCount, matchedStr) {
let handledStr = deStr(matchedStr);
return handledStr.repeat(repCount);
})
}
修改了一下正则表达式,匹配|
后面的所有字符,然后加上递归的方式解决嵌套的模板,这套方案还存在着问题,不能兼容一个字符串中包含多个模板,如[2|a][3|b]
这种情况
处理同级模板
在这里,我就陷入沉思了,我们既要处理嵌套的情况,又要处理同级的情况,应该怎么办?
- 抛开正则,通过分析分隔符的下标,将
[
和]
用一个栈保存起来,如果是[
就push进去,如果是]
就弹出了,这样就可以解决左右分隔符不对应的情况,但是问题似乎被复杂化了,因为你不知道左右分隔符的具体顺序,还得分析每一个下标的大小,再进行相应的配对 - 改进左右分隔符的匹配,重新思考,逆向思维,我们如果从左到右检索
[
的位置,但是不知道下一个符号应该出现[
还是]
,但是我们从左向右检索]
的位置,却可以确定在此之前的一个符号肯定是[
与之对应,所以我们就能够轻松的讲模板分隔出来
function deStr(str) {
let rightIndex = -1;
while ((rightIndex = str.indexOf(']')) !== -1) {
let leftIndex = str.lastIndexOf('[', rightIndex);
let subStr = str.substring(leftIndex, rightIndex + 1);
str = str.replace(subStr, deOneTemp(subStr));
}
return str;
}
function deOneTemp(str) {
let reg = /\[(\d+)\|(\w+)]/;
return str.replace(reg, function(match, repCount, matchedStr) {
return matchedStr.repeat(repCount);
});
}
这个方案勉强能够解决问题,但是每次匹配一个模板都需要用到两次indexOf()
去匹配,indexOf()
底层也是通过遍历去实现的,并且这种属于自底向上的解决方式,越到后面,需要检索的字符个数就越多,所以从时间复杂度来说,这种方案还是有点欠妥
最终解决方案
又回到我们刚开始的思考,正则匹配是有一个全局模式的,所以天然具有处理同级的能力,但很难却解决嵌套问题,但是我们函数却可以递归呀,代码如下
function deStr(str) {
let reg = /\[(\d+)\|(\w+)\]/g;
if (!reg.test(str)) {
return str;
}
let result = str.replace(reg, function(match, repCount, matchedStr) {
return matchedStr.repeat(repCount);
});
return deStr(result);
}
看到这里,是不是感觉特别简单!!!
感受
这是第一次做腾讯的实习招聘题,同时也是第一次尝试到,自己努力了两年,对前端的一种热爱,但是被否定了。这次腾讯到我们学校的笔试题就是5道算法题,根据就没有考前端相关的知识,可能别人认为你是一个应届生,不相信你的能力有多强,我只在乎你的基础,在乎你的逻辑能力。其实我以前一直以为算法没有那么重要,因为自己做过一些算法,一般的算法都不难,我一直认为只要不犯逻辑上的错误,题目都能够解决出来,并且也能够分析出哪些还可以继续优化,存在边界没有考虑到的情况,一切只是时间问题,如果时间够,肯定能交出一个满意的算法,还有一个看法,就是一些优秀的算法都是一些奇淫技巧,这些东西也只能靠自己积累,所以感觉算法不是那么重要。这次因为自己平时没有积累算法,算是失去了这次机会,大的公司需要你具有好的算法能力,也只能去适应这个环境吧,春招加油!!!