我离正确答案只差一句代码,暴风哭泣
规则
- '[‘必须’匹配]’
- ‘]’括号开头为false
- '.'可作为‘[’ 或‘]’或空白字符
- 空白字符也是可以的
输入 一个字符串
输出:如果符合规则就返回true,否则返回false
代码
function solution( data ) {
// write code here
var map = []
var tag = 0
for(let i=0;i<data.length;i++){
if(data[i]==='[')
map.push(data[i])
else if(data[i]===']'){
if(map.length===0){
if(tag>0)
tag--
else return false
}
else map.pop()
}
else if(data[i]==='.'){
if(map.length>tag)//当时没写到这句,导致没通过
tag++
}
else if(data[i]==' ')
{
continue
}
else
return false
}
if(map.length===0)
return true
else if(tag>=map.length)
return true
else
return false
}
总结
当时错误的点在于
....[
[.....
没有处理好这两种情况
…[应该返回false的
但是笔试时应该是返回了true
修改:
if(map.length!=0)//当时没写到这句,导致没通过
在对‘.’进行匹配时需要考虑如果是在‘[’左边的时候是当作字符来处理的。舍友说上边的代码像是在糊墙,下面才是美好的样子。。。
调式着突然又发现了一个bug
[.....[
[...]]]]
因为没有对‘.’的情况考虑完全
if(map.length>tag)//当时没写到这句,导致没通过
tag++
只考虑记录了‘.’的数量,在上面的第一个情况时候答案应该是false,但是按照第一版的代码却是true,因为按照运行分析是,push了两个元素,但是‘.’大于两个,tag>=map.length,所以运行返回true
正确的代码(美好的代码)【假】
function solution( data ){
var map = []
var tag = 0
var matched=0
var unmatch=0
for(let i=0;i<data.length;i++){
switch(data[i]){
case '[':
map.push(data[i])
break;
case ']':
{
if(map.length===0){
if(tag>0){
tag--
if(unmatch===0)
matched--
else
unmatch--
}
else return false
}
else map.pop()
}
break;
case '.':
{
if(map.length>matched)
matched++
else
unmatch++
tag++
}
break;
case ' ':
break;
}
}
if(map.length===0)
return true
else if(map.length===matched)
return true
else return false
}
这段代码将‘.’用三个数值保留记录
tag:’.'的个数
matched:转化为‘]’与‘[’匹配的个数
unmatch:未转化的‘.’的个数
ps:tag=matched+unmatch
思路
当左括号大于‘.’的数量的时候,matched++
否则,unmatched++
注意,在匹配‘]’的时候需要对matched也处理,因为可能‘.’一开始是作为‘[’使用,而后面却作为‘]’来使用.
[..]]][
以上匹配,如果不对matched做处理,就会返回true,因为map.length===matched,
OVER
个egg
突然发现了还有一个bug
[[...]
但是这个用第一版是正确的,到了第二版完美版是错的,
走到了这里我知道了,‘.’的情况是很难完全考虑清楚的。
舍友提供了另一种思路:
从左往右遇到‘[’和‘.’a++,遇到‘]’b++,如果b>a false
从右往左遇到‘]’和‘.’就a++,遇到‘[’就b++,如果b>a就false
完美plus版代码
function solution( data ){
var a=0
var b=0
var c=0
var d=0
for(let i=0;i<data.length;i++){
if(data[i]==='['||data[i]==='.'){
a++
}
else if(data[i]===']'){
b++
if(b>a) return false
}
else if(data[i]===' ')
continue
else return false
}
for(let j=data.length-1;j>=0;j--){
if(data[j]===']'||data[j]==='.'){
c++
}
else if(data[j]==='['){
d++
if(d>c) return false
}
else if(data[j]===' ')
continue
else return false
}
return true
}
这个代码我能想到的用例都通过了。