for循环期间读取的值不正确

时间:2014-10-10 23:35:37

标签: java debugging loops

出于某种原因,我的程序似乎一直在崩溃,因为它读取了一个令牌错误。在第362行和第363行,它读取令牌[i],无论发生什么事情,它似乎都将其视为& #39;('字符,即使它显然没有。如果我输入类似100 *(5 + 5)的内容,它会在i = 2之后调用递归0 *(5 + 5)而不是正确地去i = 4并且调用它(5 + 5)。任何帮助调试都会很棒!

package apps;

import java.io.IOException;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.Scanner;
import java.util.StringTokenizer;

import structures.Stack;

public class Expression {

/**
 * Expression to be evaluated
 */
String expr;                

/**
 * Scalar symbols in the expression 
 */
ArrayList<ScalarSymbol> scalars;   

/**
 * Array symbols in the expression
 */
ArrayList<ArraySymbol> arrays;

/**
 * Positions of opening brackets
 */
ArrayList<Integer> openingBracketIndex; 

/**
 * Positions of closing brackets
 */
ArrayList<Integer> closingBracketIndex; 

/**
 * String containing all delimiters (characters other than variables and constants), 
 * to be used with StringTokenizer
 */
public static final String delims = " \t*+-/()[]";

/**
 * Initializes this Expression object with an input expression. Sets all other
 * fields to null.
 * 
 * @param expr Expression
 */
public Expression(String expr) {
    this.expr = expr;
    scalars = null;
    arrays = null;
    openingBracketIndex = null;
    closingBracketIndex = null;
}

/**
 * Matches parentheses and square brackets. Populates the openingBracketIndex and
 * closingBracketIndex array lists in such a way that closingBracketIndex[i] is
 * the position of the bracket in the expression that closes an opening bracket
 * at position openingBracketIndex[i]. For example, if the expression is:
 * <pre>
 *    (a+(b-c))*(d+A[4])
 * </pre>
 * then the method would return true, and the array lists would be set to:
 * <pre>
 *    openingBracketIndex: [0 3 10 14]
 *    closingBracketIndex: [8 7 17 16]
 * </pe>
 * 
 * See the FAQ in project description for more details.
 * 
 * @return True if brackets are matched correctly, false if not
 */
public boolean isLegallyMatched() 
{
    Stack<Character> brack = new Stack<Character>();
    Stack<Integer> opens = new Stack<Integer>();

    openingBracketIndex = new ArrayList<Integer>();
    closingBracketIndex = new ArrayList<Integer>();



    char x;
    char y;

    String expr = this.expr;

    for(int i=0; i<expr.length(); i++)
    {
        x = expr.charAt(i);
        if(x!='(' && x!= '[' && x!=')' && x!=']')
        {
            continue;
        }
        if(x=='(' || x== '[')
        {
            opens.push(i);
            brack.push(x);  
        }
        else if(x==')' || x==']')
        {
            closingBracketIndex.add(i);
            if(opens.isEmpty())
            {
                return false;
            }
            openingBracketIndex.add(opens.pop());
            if(brack.isEmpty())
            {
                return false;
            }

            y = brack.pop();
            if(y=='(' && x==')')
            {
                continue;
            }

            else if(y=='[' && x==']')
            {
                continue;
            }
            else if(y=='{' && x=='}')
            { 
                continue;
            }

            else
            {
                return false;
            }
        }
    }

    if(!brack.isEmpty())
    {
        return false;
    }

    selectionSort(openingBracketIndex);
    if(openingBracketIndex.isEmpty()!= true)
    {
        System.out.print("Opening Bracket Index: [ ");
        for(int i=0;i<openingBracketIndex.size(); i++)
        {
            System.out.print(openingBracketIndex.get(i) + " ");
        }
        System.out.print("]");
        System.out.println();
        System.out.print("Closing bracket Index: [ ");

        for(int i=0;i<openingBracketIndex.size(); i++)
        {
            System.out.print(closingBracketIndex.get(i) + " ");
        }
        System.out.println("]");
    }
    return true;
}

/**
 * Populates the scalars and arrays lists with symbols for scalar and array
 * variables in the expression. For every variable, a SINGLE symbol is created and stored,
 * even if it appears more than once in the expression.
 * At this time, values for all variables are set to
 * zero - they will be loaded from a file in the loadSymbolValues method.
 */

public void buildSymbols() 
{
    scalars = new ArrayList<ScalarSymbol>();
    arrays = new ArrayList<ArraySymbol>();

    for(int i=0;i<expr.length();i++)
    {

        String symb = "";

        while(i<expr.length() && Character.isLetter(expr.charAt(i)))
        {
            symb = symb + expr.charAt(i);
            i++;
        }

        if(i==expr.length())
        {
            i--;
        }
        if(expr.charAt(i) == '[')
        {

            ArraySymbol arr = new ArraySymbol(symb);
            boolean dupe = checkArrDupes(arr, arrays);


            if(symb!="" && dupe == true)
            {
                arrays.add(arr);
            }
        }
        else
        {
            ScalarSymbol scal = new ScalarSymbol(symb);
            boolean dupe = checkScalDupes(scal,scalars);
            if(symb!="" && dupe==true)
            {
                scalars.add(scal);
            }
        }
    }

    // COMPLETE THIS METHOD
}

/**
 * Loads values for symbols in the expression
 * 
 * @param sc Scanner for values input
 * @throws IOException If there is a problem with the input 
 */
public void loadSymbolValues(Scanner sc) 
throws IOException {
    while (sc.hasNextLine()) {
        StringTokenizer st = new StringTokenizer(sc.nextLine().trim());
        int numTokens = st.countTokens();
        String sym = st.nextToken();
        ScalarSymbol ssymbol = new ScalarSymbol(sym);
        ArraySymbol asymbol = new ArraySymbol(sym);
        int ssi = scalars.indexOf(ssymbol);
        int asi = arrays.indexOf(asymbol);
        if (ssi == -1 && asi == -1) {
            continue;
        }
        int num = Integer.parseInt(st.nextToken());
        if (numTokens == 2) { // scalar symbol
            scalars.get(ssi).value = num;
        } else { // array symbol
            asymbol = arrays.get(asi);
            asymbol.values = new int[num];
            // following are (index,val) pairs
            while (st.hasMoreTokens()) {
                String tok = st.nextToken();
                StringTokenizer stt = new StringTokenizer(tok," (,)");
                int index = Integer.parseInt(stt.nextToken());
                int val = Integer.parseInt(stt.nextToken());
                asymbol.values[index] = val;              
            }
        }
    }
}

/**
 * Evaluates the expression, using RECURSION to evaluate subexpressions and to evaluate array 
 * subscript expressions.
 * 
 * @return Result of evaluation
 */
public float evaluate()     
{
    printScalars();
    printArrays();
    String expr = this.expr;
    System.out.println("Hello");

    float result = evaluate(expr, 0);


    return result;
}

public float evaluate(String base, int brackIndex)
{

    System.out.println("Method Start");
    Stack<Float> numStack = new Stack<Float>();
    Stack<String> opStack = new Stack<String>();
    Stack<String> op2Stack = new Stack<String>();
    Stack<Float> num2Stack = new Stack<Float>();

    float x;
    float y;
    float result;

    int swag = findParenIndexes(base);

    Stack<Integer> open = new Stack<Integer>();
    Stack<Integer> close= new Stack<Integer>();
    for(int i=0;i<base.length();i++)
    {
        if(open.size()==1 && close.size()==1)
        {
            System.out.println(open.pop() + " " + close.pop());
            break;
        }
        if(base.charAt(i)=='(' || base.charAt(i)=='[')
        {
            open.push(i);
        }
        if(base.charAt(i)==')'|| base.charAt(i)==']')
        {
            open.pop();
            close.push(i);
        }

    }
    String expr  = base;

    String orig = this.expr;

    for(int i=0;i<scalars.size();i++)
    {
        expr = expr.replaceAll(scalars.get(i).name, scalars.get(i).value + "");
    }

    System.out.println(expr);

    StringTokenizer st = new StringTokenizer(expr,delims,true);

    String[] tokens = new String[st.countTokens()];
    int z=0;
    while(st.hasMoreTokens())
    {
        tokens[z] = st.nextToken();
        z++;
    }


    for(int i=0;i<tokens.length;i++)
    {
        System.out.println(tokens[i]);
    }

    for(int i=0;i<tokens.length;i++)
    {
         String currToken = tokens[i];
         if(isNumeric(currToken))
         {
             numStack.push(Float.parseFloat(currToken));
             System.out.println("Number pushed to stack.");
         }

         if(currToken.charAt(0)=='+')
         {
             opStack.push(currToken);
             System.out.println("+ pushed to stack.");
         }

         else if(currToken.charAt(0)=='-')
         {
             opStack.push(currToken);
             System.out.println("- pushed to stack.");
         }
         else if(currToken.charAt(0)=='*')
         {
             System.out.println("Multiplying...");
             System.out.println("Current bracket index is "+ brackIndex);
             x = numStack.pop();
             i++;
             String next = tokens[i];
             if(next.charAt(0)=='(')
             {
                 try{
                 System.out.println("Evaluating " + expr.substring(i+1, swag));
                 }
                 catch(Exception e)
                 {
                     swag = findParenIndexes(expr.substring(swag,expr.length()));
                 }
                 System.out.println("i: " + i + " swag: ") ;
                 y=evaluate(expr.substring(i+1, swag), brackIndex+1);
                 result = x*y;
                 System.out.println("Multiplication worked - evaluate() returned " + result + " and jumped to the "+closingBracketIndex.get(brackIndex)+" index");
                 i = swag;
                 System.out.println("i: " + i);

                 numStack.push(result);
             }
             if(isNumeric(next))
             {
                 y = Float.parseFloat(next);
                 result = x*y;
                 System.out.println(result + " pushed to stack");
                 numStack.push(result);
             }

         }
         else if(currToken.charAt(0)=='/')
         {
             System.out.println("Dividing...");
             x = numStack.pop();
             i++;
             String next = tokens[i];
             if(next.charAt(0)== '(')
             {
                 y=evaluate(expr.substring(i+1, swag), brackIndex+1);
                 i = swag;
             }
             else
             {
                 y = Float.parseFloat(next);
             }
             if(y==0)
             {                              
                 System.out.println("Divide by Zero encountered! Please check your input");
                 throw new IllegalArgumentException();
             }

             result = x/y;
             System.out.println(result + " pushed to stack");
             numStack.push(result);
         }
         else if(currToken.charAt(0)=='(')
         {
             System.out.println("Evaluating parentheses and adding the term to the stack.");
             numStack.push(evaluate(expr.substring(i+1,swag), brackIndex+1));
             System.out.println("Jumping to " + swag);
             i = swag;
             System.out.println("i: " + i);
         }
         if(arrays.contains(currToken))
         {
             System.out.println("array variable detected. looking up" + currToken);
             int k = arrays.indexOf(currToken);
             int cool = arrays.get(k).values[10];
         }

         // 5+(5*6+(5*3)-4)-9

    }
    // (a+(b-c))*(d+4)
    while(!opStack.isEmpty())
    {
        op2Stack.push(opStack.pop());
    }
    while(!numStack.isEmpty())
    {
        num2Stack.push(numStack.pop());
    }


    while(op2Stack.isEmpty() == false)
    {

        String currOp = op2Stack.pop();

        if(currOp.charAt(0) == '+')
        {
            x = num2Stack.pop();
            y = num2Stack.pop();
            System.out.println("adding "+ x +" and "+ y);
            result = x+y;
            System.out.println(result + " pushed to stack");
            num2Stack.push(result);

            if(!opStack.isEmpty())
                System.out.println("next op... " + op2Stack.peek());
        }
        if(currOp.charAt(0) == '-')
        {
            System.out.println("subtracting...");
            x = num2Stack.pop();
            y = num2Stack.pop();
            result = x-y;
            System.out.println(result + " pushed to stack");
            num2Stack.push(result);
            if(!opStack.isEmpty())
                System.out.println("next op... " + op2Stack.peek());
        }

    }

    Float end = num2Stack.pop();
     System.out.println("pls work - " + end);

     return end;


}


private int findParenIndexes(String expr)
{
    Stack<Integer> open = new Stack<Integer>();
    Stack<Integer> close = new Stack<Integer>();

    for(int i = 0;i<expr.length();i++)
    {
        if(expr.charAt(i)=='(' || expr.charAt(i)==']')
        {
            open.push(i);
        }
        if(expr.charAt(i)==')' || expr.charAt(i)==']')
        {
            close.push(i);
            if(open.size()==1)
            {
                return close.pop();
            }
            open.pop();
        }
    }

    return 0;

        // COMPLETE THIS METHOD

}
private static boolean isNumeric(String str)  
{  
  try  
  {  
    float f = Float.parseFloat(str);  
  }  
  catch(Exception e)  
  {  
    return false;  
  }  
  return true;  
}
// test 5*(2+6-(5*3)-6)
/**
 * Utility method, prints the symbols in the scalars list
 */
public void printScalars() {
    for (ScalarSymbol ss: scalars) {
        System.out.println(ss);
    }
}

/**
 * Utility method, prints the symbols in the arrays list
 */
public void printArrays() 
{
    for (ArraySymbol as: arrays) 
    {
        System.out.println(as);
    }
}



private boolean checkArrDupes(ArraySymbol sym, ArrayList<ArraySymbol> list)
{
    if(list.size()!=0)
    {
        for(int i=0;i<list.size();i++)
        {
            if(sym==list.get(i))
            {
                return false;
            }
        }
    }
    return true;
}

private boolean checkScalDupes(ScalarSymbol sym, ArrayList<ScalarSymbol> list)
{
    if(list.size()!=0)
    {
        for(int i=0;i<list.size();i++)
        {
            if(sym==list.get(i))
            {
                return false;
            }
        }
    }
    return true;
}

private void selectionSort(ArrayList<Integer> data) 
{

    if (data == null)
        return;

    if (data.size() == 0 || data.size() == 1)
        return;

    int smallestIndex;

    int smallest;

    for (int i = 0; i < data.size(); i++)
    {
        smallest = data.get(i);
        smallestIndex = i;

        for (int z = i + 1; z < data.size(); z++) 
        {
            if (smallest > data.get(z)) 
            {
                // update smallest
                smallest = data.get(z);
                smallestIndex = z;
            }
        }
        if (smallestIndex != i)
        {
            int temp = data.get(i);
            data.set(i, data.get(smallestIndex));
            data.set(smallestIndex, temp);

            temp = closingBracketIndex.get(i);
            closingBracketIndex.set(i,closingBracketIndex.get(smallestIndex));
            closingBracketIndex.set(smallestIndex,temp);
        }

    }
}

}

0 个答案:

没有答案