【问题标题】:How to check for valid braces in javascript, programming problem?如何检查javascript中的有效大括号,编程问题?
【发布时间】:2020-06-23 22:33:52
【问题描述】:

过去几天一直在努力解决来自 codewars 的以下问题:

编写一个接受大括号字符串的函数,并确定大括号的顺序是否有效。如果字符串有效,它应该返回true,如果无效,它应该返回false

所有输入字符串都是非空的,并且只包含圆括号、方括号和花括号:()[]{}

什么是有效的?

如果所有大括号都与正确的大括号匹配,则认为大括号字符串有效。

示例

"(){}[]"   =>  True
"([{}])"   =>  True
"(}"       =>  False
"[(])"     =>  False
"[({})](]" =>  False

所以我真的被这个代码困住了,这就是我到目前为止所拥有的:

function validBraces(braces){
    let opening = [ '(', '[', '{']
    let closing = [ ')', ']', '}']
    let count = 0
    const left = []
    const right = []

    // I generate left and right arrays, left w/the opening braces from the input, right w/ the closing
    for (let i = 0; i < braces.length; i++) {
        if (opening.includes(braces[i])) {
            left.push(braces[i])
        } else if (closing.includes(braces[i])) {
            right.push(braces[i])
        }
    }
    if (braces.length % 2 !== 0) {
        return false
    }
    // I know there's no point in doing this but at one point I thought I was finishing the program and thought I would 'optimize it' to exit early, probably this is dumb haha.
    if (left.length !== right.length) {
        return false
    }
    // The juicy (not juicy) part where I check if the braces make sense
    for (let i = 0; i < left.length; i++) {
    // If the list are made up of braces like  ()[]{} add one to counter
        if (opening.indexOf(left[i]) === closing.indexOf(right[i])) {
            count += 1
        } else // If left and right are mirrored add one to the counter
            if (opening.indexOf(left[i]) === closing.indexOf(right.reverse()[i])) {
                count += 1
            }
}
    //If the counter makes sense return true
    if (count === braces.length / 2) {
        return true
    } else { return false}
}


console.log(validBraces( "()" )) //true
console.log(validBraces("([])")) //true
console.log(validBraces( "[(])" )) //false
console.log(validBraces( "[(})" )) //false
console.log(validBraces( "[([[]])]" )) //true

一些 cmets:我知道我仍然没有检查这个示例 ([])(),但我想以某种方式将它分成两个较小的检查。

感谢您阅读到此为止。尽管我不希望为我解决问题,但我会以某种方式感谢指导。由于这是一个 6kyu 问题,我可能在某种程度上过于复杂了,如果是这样,我将非常感谢有关如何更聪明地处理它的提示。

提前感谢您! :祈祷: :祈祷:

【问题讨论】:

  • 你可能想多了。归结为推动左大括号并在看到右大括号时弹出,并查看它们是否匹配。
  • 不确定这是否允许,但我在 youtube 频道上制作的最后一个视频正好解决了这个问题:youtube.com/watch?v=gQl3YrpHbkI&t=88s
  • 这能回答你的问题吗? Algorithm: optimizing 'balancing brackets'
  • 伙计们,记住,OP 明确试图自己解决这个问题。指出答案或提供解决方案,尤其是过于复杂的解决方案,并不是他们想要的。
  • @DaveNewton 谢谢老兄!正是我希望的那种提示,我会尽力按照你的建议去做。

标签: javascript


【解决方案1】:

该死!我很高兴最终自己使用这里给我的一些提示找到了解决方案:

function validBraces(braces){
    let opening = [ '(', '[', '{']
    let closing = [ ')', ']', '}']
    let arr = []
    //console.log(closing.indexOf(braces[")"]) === opening.indexOf(arr[")"]))
    for (let i = 0; i < braces.length; i++) {
        if (opening.includes(braces[i])) {
            arr.push(braces[i])
        } else
        if (closing.indexOf(braces[i]) === opening.indexOf(arr[arr.length - 1])) {
            arr.pop()
        } else return false
    } return arr.length === 0;
}

一开始我显然是想多了哈哈。感谢所有提供帮助的人!

【讨论】:

  • 很高兴你让它工作了 :) 唯一真正的“问题”(考虑到限制并不是什么大问题)是这做了很多“隐藏”迭代(includes 和多个@987654323 @)。这就是为什么你会看到很多使用对象或Map 的解决方案。但是,正如我最近了解到的那样,使用对象/地图可能会对小型集合产生性能损失,所以我猜这实际上比基于地图的解决方案更快,尽管我没有测试过.
  • 底线——干得好,热情好,好你花时间解开谜题并发布答案。如果可以的话,我会投票两次。
  • 不要忘记您可以将您的答案标记为已接受的答案!非常好的实现!
【解决方案2】:

正如 Dave 所建议的,我使用堆栈为它编写了代码:

var leftBraces="([{";
var rightBraces=")]}";

function checkBraces(braces) {
  var ok=true;
  var stack=[];
  for(var i=0; i<braces.length && ok; i++) {
    var brace=braces[i];
    if(leftBraces.includes(brace)) stack.push(brace);
    else {
      var leftBrace=stack.pop();
      if(leftBrace==undefined) ok=false;
      else if(leftBraces.indexOf(leftBrace)!=rightBraces.indexOf(brace)) ok=false;
    }
  }
  if(stack.length) ok=false;
  return ok;
}

代码只假定大括号(没有空格或其他字符)。
我正在使用与leftBracesrightBraces 匹配的string.indexOf()
此外,在for 循环中,请注意终止部分(第二个):i&lt;braces.length &amp;&amp; ok - 不是“必须”使用迭代器,如果我没记错的话,甚至可以是空的......

【讨论】:

  • 那么,您能否为好的答案投票并选出最好的?希望 - 我的... :)
【解决方案3】:

var validBraces = (s) => {
    let objO  = {'(': 0, '[': 1, '{': 2};
    let objC  = {')': 0, ']': 1, '}': 2};
    let stack = [];

    for (let i=0; i<s.length; i++) {
        if (objO.hasOwnProperty(s[i])) {
            if (stack.length === 0 || stack[stack.length-1].idx!==objO[s[i]])
                stack.push({idx: objO[s[i]], count: 1});
            else
                stack[stack.length-1].count++;
        }
        else if (objC.hasOwnProperty(s[i])) {
            if (stack.length === 0 || stack[stack.length-1].idx!==objC[s[i]])
                return false;
            else {
                stack[stack.length-1].count--;
                if (stack[stack.length-1].count===0)
                    stack.pop();
            }
        }
    }
    return stack.length === 0;
};

console.log(validBraces("(){}[]"));
console.log(validBraces("([{}])"));
console.log(validBraces("(})"));
console.log(validBraces("[(])"));
console.log(validBraces("[({})](]"));

【讨论】:

  • 似乎有些过度设计。
【解决方案4】:

这是一个简化的解决方案:

let isMatchingBraces = function(str) {
    let stack = [];
    let symbol = {
        '(': ')',
        '[': ']',
        '{': '}'
    };
    for (let i = 0; i < str.length; i += 1) {
        // If character is an opening brace add it to a stack
        if (str[i] === '(' || str[i] === '{' || str[i] === '[') {
            stack.push(str[i]);
        }
        //  If that character is a closing brace, pop from the stack, which will also reduce the length of the stack each time a closing bracket is encountered.
        else {
            let last = stack.pop();
            //If the popped element from the stack, which is the last opening brace doesn’t match the corresponding closing brace in the symbol, then return false
            if (str[i] !== symbol[last]) {
                return false
            };
        }
    }
    // After checking all the brackets of the str, at the end, the stack is not 
    // empty then fail
    if (stack.length !== 0) {
        return false
    };
    return true;
}

【讨论】:

    猜你喜欢
    • 2023-01-28
    • 2014-01-11
    • 2019-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 2021-04-10
    • 2013-10-04
    相关资源
    最近更新 更多