3

I would greatly appreciate if you could help me with this in Java.

Given two Strings, lets say String A = "(A+B)+(C)" and String B = "((A+B)+(C))" and String C = (A+B) and String D = A+(B+C) and String E = (A+(B+C))

How can I identify if the String is completely surrounded by parenthesis like String B.

In example: boolean flag(String expr) { //return false if surrounded, else true }

If expr = A, flag would return true

If expr = B, flag would return false

If expr = C, flag would return false

If expr = D, flag would return true

If expr = E, flag would return flase

Sorry if it isn't clear, but it should work for any String expression:

Assume the expression contains only Digits and Operators and Parenthesis.

Thanks. Appreciate it.

link_boy
  • 1,025
  • 4
  • 12
  • 23

3 Answers3

4

You can't do it* with a regular expression because nested parentheses isn't a regular language.

Instead iterate over the string and keep track of the nesting level by counting the number of opening and closing parentheses. For each opening parenthesis add one to the nesting level. For each closing parenthesis subtract one.

  • If you reach zero (or less) before reaching the end of the string, return true.
  • If you reach zero at the end, return false.
  • Anything else is unbalanced parentheses and shouldn't happen unless your input is invalid.

Here are some worked examples to demonstrate the principle:

(A+B)+(C)
11110        TRUE

((A+B)+(C))
12222112210  FALSE

(A+B)
11110        FALSE

A+(B+C)
0            TRUE

(A+(B+C))
111222210    FALSE

*sanely

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
  • How about a return value for the `A+(B+C)` expression? Is it a regular use-case? – Jiri Patera Apr 08 '12 at 19:50
  • Yes, that one should return true because it's not surrounded – link_boy Apr 08 '12 at 19:52
  • He maybe *meant* that, but as the question is posed now, we're only interested in the rather trivial statement whether it's surrounded or not (and not whether the parens are matched correctly). That works fine with matching against `\(.*\)` or something like that. – Voo Apr 08 '12 at 19:53
  • @Jiri No he isn't, he's solving a slightly different problem than what you think should be solved. The question is phrased.. suboptimal. – Voo Apr 08 '12 at 20:01
  • Voo, I guess, you are wrong as `(A)+(B)` returns a different value than `(A+B)`. In your solution it would return always the same value. – Jiri Patera Apr 08 '12 at 20:03
  • @Jiri Did you just delete your previous comment saying Mark was wrong and replace it with the identical one saying I'm wrong, because you still don't understand what mark is actually doing/what problem he's solving? xX – Voo Apr 08 '12 at 20:04
  • I tried to spell your name correctly there (not "Woo" but "Voo", but editing the comment was not allowed as it was more than 5 minutes old. Sorry for the deletion and confusion it might have introduced. – Jiri Patera Apr 08 '12 at 20:08
  • @Jiri Yeah I got a bit confused there, now I see what you mean. Well as I said: The string is enclosed in parens, which would fulfill the requirement. Now if we need *matched* parens, we have to go with mark's solution. – Voo Apr 08 '12 at 20:22
1

I see 2 options in your situation.

  1. Use substring method

Example:

public boolean checkForParanthesis(String str) {
 Integer last = str.length() - 1; // Get number of the last character
 String firstChar = str.substring(0); // Get first character of the string
 String lastChar = str.substring(last); // Get last character of the string
 if (firstChar.equals("(") && lastChar.equals(")")) return false;
 return true
}
  1. Use reqular expression. Perhaps it is a better solution.
Ilya Sidorovich
  • 1,530
  • 1
  • 13
  • 15
1

Mark Byers's algorithm seems to roughly be what you are looking for. Now to put it together, you have to play with for and if Java keywords and indexes. An example could be the following code. It does not validate the expression, though, so no error is thrown when e.g. the A+B) invalid expression is tested (simply the true value is returned). Inspect it and test it yourself. Hope this helps a bit...


package test;

public class Main {

  public static void main(String[] args) {
    Main m = new Main();
    m.start();
  }

  private void start() {
    /* true */
    System.out.println(isNotSurrounded("A"));
    System.out.println(isNotSurrounded("A+B"));
    System.out.println(isNotSurrounded("A+(B+C)"));
    System.out.println(isNotSurrounded("(B+C)+D"));
    System.out.println(isNotSurrounded("A+(B+C)+D"));
    System.out.println(isNotSurrounded("(A+B)+(C)"));
    System.out.println(isNotSurrounded("(A)+(B)+(C)"));
    System.out.println(isNotSurrounded("(A)+((B)+(C))+(D+E+F+(G))"));
    /* false */
    System.out.println();
    System.out.println(isNotSurrounded("(A)"));
    System.out.println(isNotSurrounded("(A+B)"));
    System.out.println(isNotSurrounded("(A+(B+C))"));
    System.out.println(isNotSurrounded("((B+C)+D)"));
    System.out.println(isNotSurrounded("(A+(B+C)+D)"));
    System.out.println(isNotSurrounded("((A+B)+(C))"));
    System.out.println(isNotSurrounded("((A)+(B)+(C))"));
    System.out.println(isNotSurrounded("((A)+((B)+(C))+(D+E+F+(G)))"));
  }

  private boolean isNotSurrounded(String expression) {
    if (expression.startsWith("(") && expression.endsWith(")") && expression.length() > 2) {
      int p = 0;
      for (int i = 1; i < expression.length() - 1; i++) {
        if (expression.charAt(i) == '(') {
          p++;
        } else if (expression.charAt(i) == ')') {
          p--;
        }
        if (p < 0) {
          return true;
        }
      }
      if (p == 0) {
        return false;
      }
    }
    return true;
  }
}

Output of the code is as follows:


true
true
true
true
true
true
true
true

false
false
false
false
false
false
false
false

Jiri Patera
  • 3,140
  • 1
  • 20
  • 14