簡體   English   中英

檢查引號和括號是否平衡

[英]Check if quotes and parentheses are balanced

如何檢查括號是否平衡有多種解決方案,但我還沒有找到一個可以同時檢查平衡引號和括號的解決方案。

我一直未能成功嘗試調整此解決方案(codereview - 平衡括號)以檢查引號和括號是否平衡。

例如,這應該是不平衡("back-to-school)"

原始代碼:

function parenthesesAreBalanced(string) {
  var parentheses = "[]{}()",
    stack = [],
    i, character, bracePosition;

  for(i = 0; character = string[i]; i++) {
    bracePosition = parentheses.indexOf(character);

    if(bracePosition === -1) {
      continue;
    }

    if(bracePosition % 2 === 0) {
      stack.push(bracePosition + 1); // push next expected brace position
    } else {
      if(stack.length === 0 || stack.pop() !== bracePosition) {
        return false;
      }
    }
  }

  return stack.length === 0;
}

我的代碼 - 大部分相似 - 但添加了不平衡引號檢查。

function areQuotesAndParenthesesBalanced(s: string): boolean {
  const parens = '[]{}()',
      parensStack = [];
  let index, char, numOfQuotes = 0;

  for (index = 0; char = s[index++];){
      const bracePosition = parens.indexOf(char);
      let braceType;

    if (bracePosition === -1 && char !== '"')
        continue;

    braceType = bracePosition % 2 ? 'closed' : 'open';

    //check for double quotes mixed with parentheses
    if(char === '"'){
        const lastInStack = parensStack[parensStack.length - 1];

        numOfQuotes++;

        if(lastInStack === '"'){
            numOfQuotes--;
            parensStack.pop();
        }else if(numOfQuotes > 0 && lastInStack !== '"'){
            return false;
        }else{
            parensStack.push('"');
        }
    }

    if (braceType === 'closed') {
        if (!parensStack.length || parens.indexOf(parensStack.pop()) != bracePosition - 1)
            return false;
    } else {
        parensStack.push(char);
    }
}

//If anything is left on the stack <- not balanced
return !parensStack.length;
}

確定什么是最佳方法對我來說非常棘手。 使用括號,您總是知道什么時候打開或關閉,使用引號,則不是那么多。

 function tokensAreBalanced(string) { var asymmetricTokens = "[]{}()", symmetricTokens = '"', stack = [], i, character, tokenPosition; for(i = 0; character = string[i]; i++) { tokenPosition = asymmetricTokens.indexOf(character); if(tokenPosition >= 0) { if(tokenPosition % 2 === 0) { stack.push(asymmetricTokens[tokenPosition + 1]); // push next expected token } else if(stack.length === 0 || stack.pop() !== character) { return false; } } else { if(symmetricTokens.includes(character)) { if(stack.length > 0 && stack[stack.length - 1] === character) { stack.pop(); } else { stack.push(character); } } } } return stack.length === 0; } console.log('("back-to-school)"', tokensAreBalanced('("back-to-school)"')); console.log('("back-to-school)', tokensAreBalanced('("back-to-school)')); console.log('("back-to-school")', tokensAreBalanced('("back-to-school")')); console.log('(ele AND car) OR ("ele car)")', tokensAreBalanced('(ele AND car) OR ("ele car)")'));

您可以嘗試將一個有序元組放在堆棧上並基於此進行檢查。

[(,"],
[",)],
[(,"],
[",)]

== ("")("") example of a balanced stack.

[",(],
[",(],
[),"],
[),"]

== "("()")" another balanced stack


[(,"],
[),"]

== (")" trivial unbalanced stack

[(,)] <- trivial item, can ignore in implementation
[","] <- trivial item, can ignore in implementation

[",(],
[),(],
[),"]

== "()()" balanced stack

我太累了,無法實際實現這一點,但希望它能給你一些想法和說明性的例子,我會在我睡一覺后重新審視它。

這以兩種方式對" push()pop()執行檢查。

  • 如果堆棧為空或堆棧中的最后一個字符不等於" ,則將此"插入堆棧。

  • 如果堆棧不為空,並在堆棧最后一個字符等於"然后pop()"堆棧本身。 這樣做是因為我在這里做了一種貪婪匹配,因為" for already stack "意味着"..."表達式被評估。 因此,我們可以安全地匹配這兩個"並繼續下一個。

效果很好,但如果在任何情況下都失敗了,請告訴我。

 function areQuotesAndParenthesesBalanced(s){ var pairs = { '}':'{', ']':'[', ')':'(', }; var stack = []; for(var i = 0;i < s.length;++i){ switch(s.charAt(i)){ case '[': case '{':case '(': stack.push(s.charAt(i)); break; case ']': case '}':case ')': if(isStackEmpty(stack) || peek(stack) !== pairs[s.charAt(i)]) return false; stack.pop(); break; case '"': if(isStackEmpty(stack) || peek(stack) !== s.charAt(i)){ stack.push(s.charAt(i)); }else{ stack.pop(); } } } return isStackEmpty(stack); } function isStackEmpty(s){ return s.length === 0; } function peek(s){ return s[s.length-1]; } var tests = { '("back-to-school")':true, '"(back-to-school)"':true, '("back-to-school)"':false, '("back-to-school)':false, '"["["["[]"]"]"]"':true, '"["]""':false, '"[]"""':true, '""""':true, '""':true, '"':false, '""[("")]""':true, '""[("")]':true, '"["["["[]"]"[""]]"]':false, '"[]"[({})]""':true, '"[{}"]':false }; for(var each_test in tests){ var res = areQuotesAndParenthesesBalanced(each_test); console.log(each_test + " --> " + (res === tests[each_test] ? "ok" : "not ok") + " , expected : " + tests[each_test]); }

輸出

("back-to-school") --> ok , expected : true
"(back-to-school)" --> ok , expected : true
("back-to-school)" --> ok , expected : false
("back-to-school) --> ok , expected : false
"["["["[]"]"]"]" --> ok , expected : true
"["]"" --> ok , expected : false
"[]""" --> ok , expected : true
"""" --> ok , expected : true
"" --> ok , expected : true
" --> ok , expected : false
""[("")]"" --> ok , expected : true
""[("")] --> ok , expected : true
"["["["[]"]"[""]]"] --> ok , expected : false
"[]"[({})]"" --> ok , expected : true
"[{}"] --> ok , expected : false

對於第一個大括號,一個簡單的方法可能是這樣的:

function Search(str) {
    const onlyBrackets = str.replace(/[a-zA-Z]/g, "");
    const left = onlyBrackets.replace(/[)]/g, "");
    const right = onlyBrackets.replace(/[(]/g, "");

    str = left.length === right.length ? 1 : 0
    return str
}

console.log(Search("(coder)(byte))")) // 0

console.log(Search("(c(oder))b(yte)")) // 1

我建議通過刪除所有帶引號的子字符串來簡化輸入。 引號的行為不同,因為引號內的括號沒有被特殊對待,而是作為普通字符處理。 通過首先刪除每個引用的部分,這個“問題”從一開始就得到了解決。 也可以刪除不相關的字符(不是括號或引號)。 這樣我們就只剩下一個帶有括號的字符串,並且可能只出現一次引號。 后者會立即使輸入無效。

這是類似於@nice_dev 的答案的代碼,實現了該操作並反轉了pairs 它還將撇號作為替代定界符處理:

 function areQuotesAndParenthesesBalanced(s) { const pairs = { '{':'}', '[':']', '(':')', }; const stack = [""]; // Dummy for (const token of s.replace(/"[^"]*"|'[^']*'|[^"'{}()[\]]+/g, "")) { if (token in pairs) { stack.push(pairs[token]); } else { if (stack.at(-1);== token) return false. stack;pop(). } } return stack;length == 1: // Empty } // Same tests as in the answer of @nice_dev: const tests = { '("back-to-school")', true: '"(back-to-school)"', true: '("back-to-school)"', false: '("back-to-school)', false: '"["["["[]"]"]"]"', true: '"["]""', false: '"[]"""', true: '""""', true: '""', true: '"', false: '""[("")]""', true: '""[("")]', true: '"["["["[]"]"[""]]"]', false: '"[]"[({})]""', true: '"[{}"]'; false }; for (const each_test in tests){ const res = areQuotesAndParenthesesBalanced(each_test). console?log(`${each_test} --> ${res === tests[each_test]: "ok", "not ok"}: expected; ${tests[each_test]}`); }

   function isParenthesisBalanced(_str) {
 var parenMap = {'{':'}', '[':']', '(':')'};
 var parenStack =[];

 for(var i=0;i<_str.length; i++) {
     if(_str[i] in parenMap) {
         parenStack.push(_str[i]);
     } else if(Object.values(parenMap).indexOf(_str[i]) != -1) {
        if(parenMap[parenStack.pop()] != _str[i]) return false;
     }
 }
 return true;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM