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, which is to say that the numbers of left ** and right parentheses ('(' and ')', respectively) are equal and that ** no prefix of the string has more )'s than ('s. ** ** Authors: R. McCloskey and < Names of Students on Team > ** Known Flaws: ... */ 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. (This corresponds to a prefix of the string having more )'s than ** ('s.) 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 are ignored. */ public static int isProperlyNested(String s) { final char LEFT_PAREN = '('; final char RIGHT_PAREN = ')'; boolean goodSoFar = true; Stack stk = new StackViaArray(s.length()); 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 k = k+1; // ignore it and 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. If the string is properly nested, a message to ** that effect is printed. Otherwise the leftmost position in the ** string at which an error was detected is pointed out. ** The program terminates in response to the user entering the empty string. */ public static void main(String[] args) { Scanner keyboard = new Scanner(System.in); System.out.println("Welcome to the parenthesis matcher."); String prompt = "\n> "; String str = getString(prompt, keyboard); while (str.length() != 0) { int m = isProperlyNested(str); if (m == -1) { System.out.println("Correctly nested"); } else { printChars(' ', m+2); // +2 accounts for the prompt System.out.println("^ Error here"); } str = getString(prompt, keyboard); } System.out.println("\nGoodbye."); } /* Displays the given string (intended to be a user prompt) and ** reads a line from the given Scanner, returning that line. */ private static String getString(String prompt, Scanner scanner) { System.out.print(prompt); return scanner.nextLine(); } /* 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); } } }