CS241: Spring 2015 -- Lecture 14, n^2 sorts

  1. Notes from your infix evaluators
    1. The code is easier to understand if there is a Stack class -- "Simplicity is next to buglessness"
    2. Testing your methods (while difficult to make yourself do) will save you time and trouble
    3. static int precedence(String operator)
      1. Cascaded if-else (wait! else?)
        public static int precedence(String operator) {
                if ("+".equals(operator)) {
                    return 2;
                }
                if ("*".equals(operator)) {
                    return 3;
                }
                if ("/".equals(operator)) {
                    return 3;
                }
                if ("-".equals(operator)) {
                    return 2;
                }
                if ("(".equals(operator)) {
                    return 0; //should be lowest
                }
                if (")".equals(operator)) {
                    return 0; //should be lowest
                }
                System.out.println("operator not recognized:" + operator);
                return -1; //should not happen
            }
      2. if-else with ||
        static private int precedence(String s) {
                if (s.equals("(") || s.equals(")")) {
                    return 0;
                } else if (s.equals("*") || s.equals("/")) {
                    return 2;
                }
                return 1;
            }
                                
      3. verbose switch statement
        private static int precedence(String s)
            {
                int p = 0;
        
                switch (s)
                {
                    case "+":
                        p = 1;
                        break;
                    case "-":
                        p = 1;
                        break;
                    case "*":
                        p = 2;
                        break;
                    case "/":
                        p = 2;
                        break;
                    case ")":
                        p = 0;
                        break;
                    case "(":
                        p = 0;
                        break;
        
                }
        
                return p;
            }
      4. switch statement
        static private int precedence(String s) {
                switch (s.charAt(0)) { 
                    case '(': return 0;             // (
                    case ')': return 0;             // )  one line for each
                    case '-': // empty stmt! Flows through...
                    case '+': return 1;   // - or +
                    case '*': case '/': return 2;   // * or / (on the same line)
                    default: return -1;              // default: none of the above, error!
                }
            }
      5. Is this a good trick?
        static String ops = "()-+*/";
        
        private static int prec(char op) {
            return ops.indexOf(""+op)/2;
        }
                                
    4. Ignoring white space
      1. with an empty statement in the if part
        if (nextToken.equals(" ")) {// do nothing!}
        else if (!isOperand(nextToken)) {
      2. Using a continue
        if (nextToken.equals(" ")) {
            continue;
         } else if (!isOperand(nextToken)) {
      3. Using a !
        if (!nextToken.equals(" ")) {
            if (!isOperand(nextToken)) {
    5. Which of these two is easier to read?
      1. if (nextToken.equals("*") || nextToken.equals("/") || nextToken.equals("+") || nextToken.equals("-")) {
      2. if (operator(nextToken)) {
    6. the static boolean operator(String) method
      1. The first thing you'd think of
        static boolean operator(String s) {
        if (s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/") || s.equals("(") || s.equals(")")) {
            return true;
            }
        return false;
        }
      2. Using String.contains(String)
        static boolean operator(String s) { 
            return "*-+/()".contains(s);
        }
      3. Using String.indexOf(String) and a constant
        private static final String OPERATORS = "+-*/";
        private static final String TOKENS = OPERATORS + "() ";
        
        private static boolean isOperator(String s)
        {
            return OPERATORS.indexOf(s) != -1;
        }
  2. Three n^2 sorts
    1. Bubble sort - n-1 passes, each compares each pair of adjacent elements and swaps if ooo
          iterate n-1 times {
              for the ith element (i ranging from 0 to n-1) {
                  if (out of order (relative to the next element) 
                      swap ith and ith+1th values, ith and next value?
              }
          }
                      
    2. Selection sort - n-1 passes; the ith finds the smallest remaining (i.e. at i or more) element and swaps it to position i
          iterate n-1 times (i ranging from 0 to n-1){
                      swap ith and indexOfSmallest from i to n-1?
              }
          }
      
                      
    3. Insertion sort - repeatedly insert one more element into a sorted list
          iterate n-2 times (i ranging from 1 to n-2){
              for the ith element {
                  insert it where it goes in the sorted list above it (must shift down the list first)
              }
          }
                      
  3. How many operations?
    1. bubble sort
    2. selection sort
    3. insertion sort
  4. You can trade space for time (and vice-versa). E.g. calculating Fibonacci numbers.