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

时间:2013-03-01 08:32:22

标签: c# string stack

假设我有一个字符串“(付费)+(8个工作小时)+(公司规则)”。现在我想检查这个完整的字符串是否用括号括起来。基本上我想检查字符串是否是这样:“((付费)+(8个工作小时)+(公司规则))”。如果它已被括号括起来,那么我将原样保留,否则我将括号应用于完整的字符串,以便输出为:“((付费)+(8个工作小时)+(公司规则)) “。通过计算括号的数量,我无法解决这个问题。

有人可以建议一个解决方案吗?

6 个答案:

答案 0 :(得分:10)

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

示例:

0

答案 1 :(得分:2)

使用堆栈..就像当你找到一个(支架推它,当你看到)弹出堆栈.. 最后,当完全解析字符串时,堆栈应该为空......这将确保括号不会丢失..

在你的情况下,如果在堆栈之间变为空,则整个字符串没有周围的括号

例如: 输入字符串:

  

(付费)+(8个工作小时)+(公司规则)

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

而对于字符串:

  

((已付款)+(8个工作小时)+(公司规则))

堆栈不会是空的,直到最后一个)出现。

希望这会有所帮助......

答案 2 :(得分:1)

测试

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;
}

限制

如果有更多递归括号,例如((..)) + ((..))

,则不应使用

答案 3 :(得分:0)

为确保有括号,您只需添加它们即可:

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.
}

答案 4 :(得分:0)

您可以使用类似堆栈的内容来检查正确数量的括号。计算每个开口并倒数每个闭合支架。相同数量的开合括号意味着它匹配。如果你的计数为零时遇到一个右大括号,那就是不匹配。如果你想知道你的字符串是否被paranthesises完全包围,请检查它们是否都匹配,然后检查你的字符串是否以一个字符串开头。

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.");
  }
}

答案 5 :(得分:0)

找到右括号索引

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;
}