Sunday, 23 October 2011

4.14 - END


4_14. Compile class ArithmeticExpression. Create an instance using the exception example given in the table above "(a+B)". Run method isValid(). The method should return false.

4.14. Worked, done.

4_15. Edit method isValid(), to take care of the other 9 rules given in the table above. For each implementation check the method by using the exception example given in the table above.

4.15. I added some methods to help with the changes. This was quite a complicated task, but I believe I came up with good solutions to it.


public boolean isValid()
{
    int numoperands = 0;
    int numoperators = 0;
    int numopen = 0;
    HashSet Caseoperandset = new HashSet();
    boolean tempIsValid=true;
    if(!expression.substring(0,1).equals("(") || !expression.substring(0,1).equals(")"))
       tempIsValid = false;
    for (int i =0; i<expression.length();i++)
    {
        Character tempCharacter=new Character(expression.charAt(i));
        boolean canTemp2 = i+1<expression.length();
        if(canTemp2) { Character temp2 = new Character(expression.charAt(i+1));
        if(!operatorSet.contains(tempCharacter) && !operandSet.contains(tempCharacter) && !bracketSet.contains(tempCharacter))
                tempIsValid= false;
        if(checkIfClosedParentheses(tempCharacter)) {
            if(operandSet.contains(temp2) && canTemp2)
                tempIsValid = false;
        }
        if(operatorSet.contains(tempCharacter)) {
           numoperators++;
           if(checkIfClosedParentheses(temp2) && canTemp2)
                tempIsValid = false; }
        if(operandSet.contains(tempCharacter)) {
           numoperands++;
           Caseoperandset.add(tempCharacter); }
           if(checkIfOpenParentheses(temp2) && canTemp2)
               {tempIsValid = false;}
        if(checkIfOpenParentheses(tempCharacter))
           numopen++; }
        else
        {
        if(!operatorSet.contains(tempCharacter) && !operandSet.contains(tempCharacter) && !bracketSet.contains(tempCharacter))
                tempIsValid= false;
        if(operatorSet.contains(tempCharacter))
           numoperators++;
        if(operandSet.contains(tempCharacter)) {
           numoperands++;
           Caseoperandset.add(tempCharacter); }
        if(checkIfOpenParentheses(tempCharacter))
           numopen++;
        }
    }
    if(checkParentheses(expression) || numoperands != numoperators+1 || numopen != numoperators || !checkIfConsecutiveOperands(Caseoperandset) || checkIfOperandsDouble(Caseoperandset))
       tempIsValid = false;
    return tempIsValid;
}

public boolean checkIfConsecutiveOperands(HashSet characters)
{
    boolean Consecutive = true;
    for(char c='a';c<=characters.size();c++)
    {
        if(!operandSet.contains(c))
           Consecutive = false;
    }//for
    return Consecutive;
}

public boolean checkIfOperandsDouble(HashSet characters)
{
    for(char c='a'; c<characters.size(); c++) {
       for(char z='a'; c<characters.size(); z++)
       {
           if(c == z)
              return true;
        }
    }
    return false;
}
public static boolean checkIfOpenParentheses(Character c)
{
     if(c.toString().equals("("))
        return true;
     else return false;
}

public static boolean checkIfClosedParentheses(Character c)
{
     if(c.toString().equals(")"))
        return true;
     else return false;
}

public static boolean checkParentheses(String s) { //Mark Byers method to find whether parenthesis are equal by checking the nesting level.
    int nesting = 0;
    for (int i = 0; i < s.length(); ++i)
    {
        char c = s.charAt(i);
        switch (c) {
            case '(':
                nesting++;
                break;
            case ')':
                nesting--;
                if (nesting < 0) {
                    return false;
                }
                break;
        }
    }
    return nesting == 0;
}


4_16. What changes have to be made to modify class ArithmeticExpression to use double values rather than int values.

4.16. You would have to change all your int values into doubles (but not in your loops, i believe). This seems unnecessary for now; however, because everything seems to be working fine with ints.

4_17. When the user attempts to divide by zero, an "ArithmeticException (divide by zero)" error is thrown. The ArithmeticException class is part of the APCS Java Subset.
http://www.cs.duke.edu/csed/AP/subset/doc/index.html
Place a check in method evaluate() that catches this runtime error.

4.17.        case '+': result=operand1+operand2; break;
                case '*': result=operand1*operand2; break;
                case '/': {if(operand1 == 0) {System.out.println("Cannot divide by zero."); return 0;}      result=operand2/operand1; break;}
                case '-': result=operand2-operand1; break;

     Simply checked if it's zero. If it was a gave an error and set the case to 0.

4_18. Edit class ArithmeticExpression to include a method that converts the infix expression represented by the String expression to a postfix expression..
Public String infixToPostfix()
The algorithm for this method requires two stacks, one to build the postfix expression, and an auxiliary stack for temporarily holding operators.
Moving through the expression from the left.
Ignore open parentheses
Push operands on the "build" stack.
Push operators on the auxiliary stack.
On closed parentheses, pop the operator from the auxiliary stack and push it onto the "build" stack.
After processing all the characters in the expression String the "build" stack will contain the characters making up the postfix string in order from bottom to top of the stack.
Construct the postfix String (you can use the empty auxiliary to help) and return the postfix String.

4.18. Took a while... with a bit of help from Gershon's blog to find some of my compiling errors i finally got it:


public String infixToPostfix()
 {
  ArrayListStack operatorStack = new ArrayListStack();
  String postfix = "";
  for(int i=0;i<expression.length();i++)
  {
      char c = expression.charAt(i);
      if(operandSet.contains(c))
          postfix=postfix+Character.toString(c);
      if(operatorSet.contains(c))
          operatorStack.push(c);
      if(Character.toString(c).equals(")"))
          postfix = postfix + Character.toString((Character)operatorStack.pop()); //thanks to Gershon I found the casting issue that was bothering me for ages...
  }
  return postfix;
 }

No comments:

Post a Comment