7

I want to be able to get string and check if the Parentheses are valid.

For example:

"(ew)[]" - this will be valid.

"(ew[)]" - this will be not valid.

This is what I have tried:

public static bool CheckString(string input)
{
    int braceSum = 0, squareSum = 0, parenSum = 0;

    foreach (char c in input)
    {  
        if (c == '{')
            braceSum++;
        if (c == '}')
            braceSum--;
        if (c == '[')
            squareSum++;
        if (c == ']')
            squareSum--;
        if (c == '(')
            parenSum++;
        if (c == ')')
            parenSum--;

        //check for negatives (pair closes before it opens)
        if (braceSum < 0 || squareSum < 0 || parenSum < 0)
            return false;
    }

    return (braceSum == 0 && squareSum == 0 && parenSum == 0);
}

So in both cases my code will return true. Do you have any suggestions about what I need to add in order for the program to work correctly?

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
danny kob
  • 171
  • 1
  • 2
  • 12
  • 6
    Have a look at: [Check for Balanced Parenthesis in a String](https://www.codeproject.com/Tips/1175562/Check-for-Balanced-Parenthesis-in-a-String) – Mighty Badaboom Sep 14 '18 at 08:13
  • @NikhilKS Maybe he has not knowledge or is not confident enough with Regex, sometimes Regex could be intimidating. – Cleptus Sep 14 '18 at 08:24

1 Answers1

13

Try classic Stack-based validation:

public static bool CheckString(string input) {
  if (string.IsNullOrEmpty(input))
    return true;

  Stack<char> brackets = new Stack<char>();

  foreach (var c in input) {
    if (c == '[' || c == '{' || c == '(')
      brackets.Push(c);
    else if (c == ']' || c == '}' || c == ')') {
      // Too many closing brackets, e.g. (123))
      if (brackets.Count <= 0)
        return false;

      char open = brackets.Pop();

      // Inconsistent brackets, e.g. (123]
      if (c == '}' && open != '{' ||
          c == ')' && open != '(' ||
          c == ']' && open != '[')
        return false;
    }
  }

  // Too many opening brackets, e.g. ((123) 
  if (brackets.Count > 0)
    return false;

  return true;
}

Demo:

 string[] tests = new string[] {
    "123",
    "(123)",
    "(1(23)",
    "(12)3)",
    "(ew)[]",
    "(ew[)]",
    "[12(34]56)",
    "[1+2(3+4)][5+6)",
  };

  string report = string.Join(Environment.NewLine, tests
    .Select(test => $"{test,-15} : {(CheckString(test) ? "Valid" : "Invalid")}"));

  Console.Write(report);

Outcome:

123             : Valid
(123)           : Valid
(1(23)          : Invalid
(12)3)          : Invalid
(ew)[]          : Valid
(ew[)]          : Invalid
[12(34]56)      : Invalid
[1+2(3+4)][5+6) : Invalid
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • Have not tested, could be wrong, but this could allow `[12(34]56)` because of not differentiating between the three types, right? – Cleptus Sep 14 '18 at 08:23
  • @bradbury9: No, `[12(34]56)` is *Invalid* (see my edit - Demo); if not tested, let's do it ;) – Dmitry Bychenko Sep 14 '18 at 08:25
  • @DmitryBychenko can we also check "[1+2(3+4)][5+6)" this expression. Can we also check sequence of it ? – Ameya Deshpande Jul 08 '21 at 06:40
  • @Ameya Deshpande:, well `"[1+2(3+4)][5+6)"` is *invalid*, as we might expect: the last `[` doesn't have corresponding closing bracket, but `)`. See my edit, please – Dmitry Bychenko Jul 08 '21 at 08:04