刚解析完回文字符串的思路,趁热打铁把判断表达式是否闭合也理一理。此题中闭合元素只考虑圆括号(),方括号[],大括号{}。三种。方法不止一种。这只是我能想到的。
如果单纯的判断表达式是否闭合,不返回未闭合元素的下标。
- 1,提取表达式中所有括号;
- 2, 数量为奇数或者依右括号开始}])直接返回false;
- 3, 否则,判断是{,[(的时候入栈,否则出栈, 如果最后数量是0返回true,否则false
function isClose(str) {
let len = str.length;
let reg = /(\[|\]|\{|\}|\(|\))/g;
let arr = str.match(reg);
if (arr.length % 2 || /(\}|\]|\))/.test(arr[0])) {
return false
} else {
let stack = [];
while (arr.length) {
let _v = arr.shift()
if (/(\[|\{|\()/.test(_v)) {
console.log(1);
stack.push(_v)
} else {
stack.pop()
}
};
console.log(stack)
return !stack.length
}
}
复制代码
判断是否闭合,并返回下标呢。
利用双指针加字典解法。
- 1.设置头尾双指针。
- 2.分别判断头尾两个指针对应的元素是否是闭合元素,如果不是闭合元素,头指针向右移动,尾指针向左移动,直到两个指针指向的都是闭合元素。
- 3.判断头尾对应的元素是不是闭合元素,不是则返回下标,重复2步骤。
var dir = {
"{": "}",
"[": "]",
"(": ")",
")": "(",
"}": "{"
}
function atWhereNoClose(str) {
let len = str.length;
let left = 0;
let right = len - 1;
let flg = true;
while (left < right) {
while (!/(\[|\{|\()/.test(str[left]) && left < right) {
left++
}
while (!/(\}|\]|\))/.test(str[right]) && left < right) {
right--
}
if (dir[str[left]] !== str[right]) {
if (dir[str[left]] && left <= right) {
flg = left
break;
}
} else {
left++
right--
}
}
return flg;
}
console.log(atWhereNoClose("{[[ab}}"))
console.log(atWhereNoClose("{ab}"))
console.log(atWhereNoClose("{({[ab]})}"))
console.log(atWhereNoClose("ab}"))
复制代码