判断表达式是否正确闭合,返回未闭合元素的下标。

1,215 阅读1分钟

刚解析完回文字符串的思路,趁热打铁把判断表达式是否闭合也理一理。此题中闭合元素只考虑圆括号(),方括号[],大括号{}。三种。方法不止一种。这只是我能想到的。

如果单纯的判断表达式是否闭合,不返回未闭合元素的下标。

  • 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}"))