import java.util.Scanner; // for use by main() method, only for testing. /* This class has a method that tests to see if the parentheses in a given ** String are properly nested. ** ** Its main purpose is to illustrate the use of a stack. ** ** Author: R. McCloskey ** Date: February 2020 */ public class ParenthesisMatcher { /* Returns -1 if the parentheses in the given String (s) are properly ** nested. Otherwise, returns the lowest-numbered position in s where a ** violation of proper nesting occurs. There are two kinds of violations, ** one being an occurrence of a right parenthesis that has no mate to its ** left. The other is that the string has unmatched left parentheses (and ** thus would have to be extended with matching right parentheses in order ** to be valid). In the latter case, the value returned is s.length(). ** Any characters in s that are non-parentheses ('(' or ')') are ignored. */ public static int isProperlyNested(String s) { final char LEFT_PAREN = '('; final char RIGHT_PAREN = ')'; boolean goodSoFar = true; Stack stk = new StackViaArray(); //Stack stk = new StackViaLink1(); int k = 0; while (k != s.length() && goodSoFar) { char ch = s.charAt(k); if (ch == LEFT_PAREN) { // ch is a left parenthesis, stk.push(ch); // so push it onto the stack k = k+1; // and advance to next position of s } else if (ch == RIGHT_PAREN) { if (stk.isEmpty() || stk.topOf() != LEFT_PAREN) { goodSoFar = false; // there is no matching left paren on stack } else { stk.pop(); // ch is matched by a left parenthesis on the stack, k = k+1; // so pop it off and advance to next position of s } } else { // ch is neither a left nor right parenthesis, so ignore it k = k+1; // advance to next position of s } } // At this point, s has passed the test iff we've reached its end // and the stack is empty. In that case, set k to -1, indicating // success. Otherwise the value of k indicates the position in s // where an error was found. if (k == s.length() && stk.isEmpty()) { k = -1; } return k; } /* For each string entered by the user, it is tested for proper ** parenthesis nesting. The program terminates after the user enters ** the empty string. */ public static void main(String[] args) { Scanner keyboard = new Scanner(System.in); String str; do { System.out.print("\nEnter string to test for proper parenthesis nesting:"); str = keyboard.nextLine(); int m = isProperlyNested(str); if (m == -1) { System.out.println(" Correctly nested"); } else { System.out.println(str); printChars(' ', m); System.out.println("^ Error here"); } } while (str.length() != 0); } /* Prints the specified character the specified number of times. */ private static void printChars(char ch, int times) { for (int i=0; i != times; i++) { System.out.print(ch); } } }