1

電卓は現在、ほとんど機能しています。読み込んだすべての方程式に対して同じ答えが得られるようになりましたか?

the output ends up as: 49+62*61-36 15.666666666666668 4/64 15.666666666666668 (53+26) 15.666666666666668 0*72 15.666666666666668 21-85+75-85 15.666666666666668 90*76-50+67 15.666666666666668 46*89-15 15.666666666666668 34/83-38 15.666666666666668 20/76/14+92-15 15.666666666666668 5*10/3-1 15.666666666666668

そこに各方程式の答えがある代わりに?

私の方法で何かを逃したことがありますか?

ありがとう

すべてのコードを以下に示します。どんな助けでも大歓迎です。

スタック クラス:

 import java.util.Iterator;
 import java.util.NoSuchElementException;

public class myStack<Item> implements Iterable<Item> {
private int N; // size of the stack
private Node first; // top of stack

private class Node {
    private Item item;
    private Node next;
}

/**
 * Create an empty stack.
 */
public myStack() {
    first = null;
    N = 0;
    assert check();
}

public boolean isEmpty() {
    return first == null;
}

public int size() {
    return N;
}

public void push(Item item) {
    Node oldfirst = first;
    first = new Node();
    first.item = item;
    first.next = oldfirst;
    N++;
    assert check();
}

public Item pop() {
    if (isEmpty())
        throw new NoSuchElementException("Stack underflow");
    Item item = first.item; // save item to return
    first = first.next; // delete first node
    N--;
    assert check();
    return item; // return the saved item
}

public Item peek() {
    if (isEmpty())
        throw new NoSuchElementException("Stack underflow");
    return first.item;
}

public String toString() {
    StringBuilder s = new StringBuilder();
    for (Item item : this)
        s.append(item + " ");
    return s.toString();
}

// check internal invariants
private boolean check() {
    if (N == 0) {
        if (first != null)
            return false;
    } else if (N == 1) {
        if (first == null)
            return false;
        if (first.next != null)
            return false;
    } else {
        if (first.next == null)
            return false;
    }

    // check internal consistency of instance variable N
    int numberOfNodes = 0;
    for (Node x = first; x != null; x = x.next) {
        numberOfNodes++;
    }
    if (numberOfNodes != N)
        return false;

    return true;
}

public Object[] toArray(String[] elementData) {
    return (Object[]) elementData.clone();
}

public Iterator<Item> iterator() {
    return new ListIterator();
}

// did not implement remove as it was not needed
private class ListIterator implements Iterator<Item> {
    private Node current = first;

    public boolean hasNext() {
        return current != null;
    }

    public void remove() {
        throw new UnsupportedOperationException();
    }

    public Item next() {
        if (!hasNext())
            throw new NoSuchElementException();
        Item item = current.item;
        current = current.next;
        return item;
    }
}
}

配列リスト クラス

import java.util.Arrays;

public class myArrayList<Item>{

private Object[] myStore;
private int actSize = 0;

public myArrayList() {
    myStore = new Object[100];
}

public Object get(int index) {
    if (index < actSize) {
        return myStore[index];
    } else {
        throw new ArrayIndexOutOfBoundsException();
    }
}
public void add(Object obj) {
    if (myStore.length - actSize <= 0) {
        increaseListSize();
    }
    myStore[actSize++] = obj;
}

public Object remove(int index) {
    if (index < actSize) {
        Object obj = myStore[index];
        myStore[index] = null;
        int tmp = index;
        while (tmp < actSize) {
            myStore[tmp] = myStore[tmp + 1];
            myStore[tmp + 1] = null;
            tmp++;
        }
        actSize--;
        return obj;
    } else {
        throw new ArrayIndexOutOfBoundsException();
    }

}

public int size() {
    return actSize;
}

private void increaseListSize() {
    myStore = Arrays.copyOf(myStore, myStore.length * 2);
}

@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
    if (a.length < size())
        // Make a new array of a's runtime type, but my contents:
        return (T[]) Arrays.copyOf(myStore, size(), a.getClass());
    System.arraycopy(myStore, 0, a, 0, size());
    if (a.length > size())
        a[size()] = null;
    return a;
}


}

方程式処理用の TestClass

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
 import java.util.StringTokenizer;

public class TestClass {

private static final int LEFT_ASSOC = 0;
private static final int RIGHT_ASSOC = 1;
static String OPERATORS1 = "+-*/()";

// Operators
private static final Map<String, int[]> OPERATORS = new HashMap<String, int[]>();
static {
    // Map<"token", []{precedence, associativity}>
    OPERATORS.put("+", new int[] { 0, LEFT_ASSOC });
    OPERATORS.put("-", new int[] { 0, LEFT_ASSOC });
    OPERATORS.put("*", new int[] { 5, LEFT_ASSOC });
    OPERATORS.put("/", new int[] { 5, LEFT_ASSOC });
    OPERATORS.put("(", new int[] {1, LEFT_ASSOC});
    OPERATORS.put(")", new int[] {1, LEFT_ASSOC});
}

private static boolean isOperator(String token) {
    return OPERATORS.containsKey(token);
}

// Test associativity of operator token
private static boolean isAssociative(String token, int type) {
    if (!isOperator(token)) {
        throw new IllegalArgumentException("Invalid token: " + token);
    }

    if (OPERATORS.get(token)[1] == type) {
        return true;
    }
    return false;
}

// Compare precedence of operators.
private static final int cmpPrecedence(String token1, String token2) {
    if (!isOperator(token1) || !isOperator(token2)) {
        throw new IllegalArgumentException("Invalid tokens: " + token1
                + " " + token2);
    }
    return OPERATORS.get(token1)[0] - OPERATORS.get(token2)[0];
}

public static String[] infixToRPN(String[] inputTokens) {
    myArrayList<String> out = new myArrayList<String>();
    myStack<String> stack = new myStack<String>();
    // For each token
    for (String token : inputTokens) {
        StringTokenizer tokens = new StringTokenizer(token,OPERATORS1,true);
        while (tokens.hasMoreTokens()) {
            token = tokens.nextToken();


            // If token is an operator
            if (isOperator(token)) {
                // While stack not empty AND stack top element
                // is an operator
                while (!stack.isEmpty() && isOperator(stack.peek())) {
                    if ((isAssociative(token, LEFT_ASSOC) && cmpPrecedence(
                            token, stack.peek()) <= 0)
                            || (isAssociative(token, RIGHT_ASSOC) && cmpPrecedence(
                                    token, stack.peek()) < 0)) {
                        out.add(stack.pop());
                        continue;
                    }
                    break;
                }
                // Push the new operator on the stack
                stack.push(token);
            }
            // If token is a left bracket '('
            else if (token.equals("(")) {
                stack.push(token); 
            }
            // If token is a right bracket ')'
            else if (token.equals(")")) {
                while (!stack.isEmpty() && !stack.peek().equals("(")) {
                    out.add(stack.pop());
                }
                stack.pop();
            }
            // If token is a number
            else {
                out.add(token);
            }
        }
        while (!stack.isEmpty()) {
            out.add(stack.pop());
        }
    }
    String[] output = new String[out.size()];
    return out.toArray(output);
}

public static double RPNtoDouble(String[] tokens) {
    myStack<String> stack = new myStack<String>();

    // For each token

    for (String token : tokens) {
        //System.out.println( "Working this token: " + token );
        // If the token is a value push it onto the stack
        if (!isOperator(token)) {
            stack.push(token);
        } else {
            // Token is an operator: pop top two entries
            Double d2 = Double.valueOf(stack.pop());
            Double d1 = Double.valueOf(stack.pop());

            // Get the result
            Double result = token.compareTo("+") == 0 ? d1 + d2 : token
                    .compareTo("-") == 0 ? d1 - d2
                            : token.compareTo("*") == 0 ? d1 * d2 : d1 / d2;

            // Push result onto stack
            stack.push(String.valueOf(result));
        }
    }

    return Double.valueOf(stack.pop());
}

static public void main(String[] args) throws IOException {
    File file = new File("testEquations.txt");
    String[] lines = new String[1];

    try {
        FileReader reader = new FileReader(file);
        @SuppressWarnings("resource")
        BufferedReader buffReader = new BufferedReader(reader);
        int x = 0;
        String s;
        while ((s = buffReader.readLine()) != null) {
            lines[x] = s;
            x++;
        }
    } catch (IOException e) {
        System.exit(0);
    }
    // test printing string array
    for (String s : lines) {
        System.out.println("" + s);
        String[] output =infixToRPN(lines);
        System.out.println(RPNtoDouble(output));

    }


}

}
4

1 に答える 1

3

あなたの問題はここにあります:

String[] lines = new String[1];

    try {
        FileReader reader = new FileReader(file);
        @SuppressWarnings("resource")
        BufferedReader buffReader = new BufferedReader(reader);
        int x = 0;
        String s;
        while ((s = buffReader.readLine()) != null) {
            lines[x] = s;
            x++;
        }
        ...

サイズ = 1 で文字列の配列を定義しますが、x がこの配列の境界から出ているかどうかをループ内でチェックしません。

次のように考えてください:

int Size = // define the size..;
String[] lines = new String[Size];
...
while (x < Size && (s = buffReader.readLine()) != null)) {
            lines[x] = s;
            x++;
        }

x が Size よりも大きくx < Sizeなると、false と評価され、ループから抜け出します。

ArrayIndexOutOfBoundsExceptionを取得しているエラーの 1 つについて:

配列が不正なインデックスでアクセスされたことを示すためにスローされます。インデックスが負であるか、配列のサイズ以上です。(ソース

他のエラーNoSuchElementException :

Enumeration の nextElement メソッドによってスローされ、列挙 ( source ) にそれ以上要素がないことを示します。

別の問題はここにあります:

// test printing string array
    for (String s : lines)
    {
        System.out.println("" + s);
        String[] output =infixToRPN(lines);
        System.out.println(RPNtoDouble(output));

    }

methodではsなくを渡す必要があります。同じ入力を与えるため、同じ出力が得られるのはそのためです。linesinfixToRPN

's' のような文字列でinfixToRPNはないことを覚えておいてください。String []

于 2012-11-26T23:26:55.670 に答える