如何在字符串中找到匹配的大括号对

本文关键字:字符串 | 更新日期: 2023-09-27 18:01:36

假设我有一个字符串"(paid for) +(8个工作小时)+(公司规则)"。现在我要检查这个完整的字符串是否被圆括号包围。基本上,我想检查字符串是否像这样:"((支付)+(8个工作小时)+(公司规则))"。如果它已经被括号包围,那么我将保持原样,否则我将对完整的字符串应用括号,以便输出是:"((paid for) +(8个工作小时)+(公司规则))"。通过计算括号的个数,我无法解决这个问题。

谁能提出一个解决方案?

如何在字符串中找到匹配的大括号对

Stack是一个好主意,但是当您想看到完整的字符串是否被父括号包围时,我建议您将遇到的打开父括号的索引放在Stack上。这样,每次在堆栈上弹出一个项目时,检查它是否为0,这意味着与此关闭父级对应的打开父级位于字符串的开头。检查最后一个结束父括号的结果将告诉您是否需要添加父括号。

的例子:

String s = "((paid for) + (8 working hours) + (company rules))";
var stack = new Stack<int>();
bool isSurroundedByParens = false;
for (int i = 0; i < s.Length; i++) {
    switch (s[i]) {
    case '(':
        stack.Push(i);
        isSurroundedByParens = false;
        break;
    case ')':
        int index = stack.Any() ? stack.Pop() : -1;
        isSurroundedByParens = (index == 0);
        break;
    default:
        isSurroundedByParens = false;
        break;
    }
}
if (!isSurroundedByParens) {
    // surround with parens
}

使用堆栈。就像当你找到一个(括号推入它,当你看到)弹出堆栈…最后,当字符串被完全解析后,堆栈应该是空的…这将确保括号没有丢失。

在你的例子中

如果在堆栈之间变为空,那么整个字符串

就没有括号了例如

:输入字符串:

(带薪)+(8小时工作)+(公司规定)

第一个(将被推入,当它遇到),它将弹出堆栈,现在检查是否有更多的字符串要解析,堆栈不是空的。如果堆栈为空,则表示整个字符串不在括号中。

对于字符串:

((有偿)+(8小时)+(公司规定))

在最后一个)出现之前,

堆栈不会为空。

查找右括号索引

public int FindClosingBracketIndex(string text, char openedBracket = '{', char closedBracket = '}')
{
            int index = text.IndexOf(openedBracket);
            int bracketCount = 1;
            var textArray = text.ToCharArray();
            for (int i = index + 1; i < textArray.Length; i++)
            {
                if (textArray[i] == openedBracket)
                {
                    bracketCount++;
                }
                else if (textArray[i] == closedBracket)
                {
                    bracketCount--;
                }
                if (bracketCount == 0)
                {
                    index = i;
                    break;
                }
            }
            return index;
}

测试

static void Main()
{
    Console.WriteLine("Expected: {0}, Is: {1}", false, IsSurrounded(""));
    Console.WriteLine("Expected: {0}, Is: {1}", false, IsSurrounded("("));
    Console.WriteLine("Expected: {0}, Is: {1}", false, IsSurrounded(")"));
    Console.WriteLine("Expected: {0}, Is: {1}", true, IsSurrounded("()"));
    Console.WriteLine("Expected: {0}, Is: {1}", false, IsSurrounded("(()"));
    Console.WriteLine("Expected: {0}, Is: {1}", false, IsSurrounded("())"));
    Console.WriteLine("Expected: {0}, Is: {1}", true, IsSurrounded("(.(..)..(..)..)"));
    Console.WriteLine("Expected: {0}, Is: {1}", false, IsSurrounded("(..)..(..)"));
    Console.WriteLine("Expected: {0}, Is: {1}", false, IsSurrounded("(..)..(..)..)"));
    Console.WriteLine("Expected: {0}, Is: {1}", false, IsSurrounded("(.(..)..(..)"));
}

快速

  • 没有堆栈
  • 不循环整个字符串

如果第一个左括号有对应的右括号,则结果不可能为真。最后一个右括号也是一样。

static bool IsSurrounded(string text)
{
    if (text.Length < 2 || text.First() != '(' || text.Last() != ')')
        return false;
    for (var i = 1; i < text.Length - 1; i++)
    {
        if (text[i] == ')')
            return false;
        if (text[i] == '(')
            break;
    }
    for (var i = text.Length - 2; i > 0; i--)
    {
        if (text[i] == '(')
            return false;
        if (text[i] == ')')
            break;
    }
    return true;
}

限制

不能在递归括号较多的情况下使用,如((..)) + ((..))

要确保有括号,您可以简单地添加它们:

text = "(" + text + ")"

否则Botz3000建议的堆栈:

string text = "(paid for)";
Stack<int> parenthesis = new Stack<int>();
int last = 0;
for (int i = 0; i < text.Length; i++)
{
    if (text[i] == '(')
        parenthesis.Push(i);
    else if (text[i] == ')')
    {
        last = parenthesis.Pop();
    }
}
if (last == 0)
{
    // The matching parenthesis was the first letter.
}

您可以使用类似堆栈的东西来检查括号的正确数量。为每个开始和每个结束大括号计数。相同数量的开始和结束大括号表示匹配。如果在计数为零时遇到右括号,那就是不匹配。如果你想知道你的字符串是否完全被大括号包围,检查它们是否都匹配,然后检查你的字符串是否以一个开头。

static void BraceMatch(string text)
{
  int level = 0;
  foreach (char c in text)
  {
    if (c == '(')
    {
      // opening brace detected
      level++;
    }
    if (c == ')')
    {
      level--;
      if (level < 0)
      {
        // closing brace detected, without a corresponding opening brace
        throw new ApplicationException("Opening brace missing.");
      }
    }
  }
  if (level > 0)
  {
    // more open than closing braces
    throw new ApplicationException("Closing brace missing.");
  }
}