计算器现在几乎正常工作。它现在为它读入的每个方程给出了相同的答案?
输出结束为: 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 七十六分之二十○/ 14 + 92-15 15.666666666666668 5 * 10 / 3-1 15.666666666666668
而不是每个等式都有答案吗?
我的方法中是否遗漏了一些东西?
由于
所有代码如下所示。任何帮助将不胜感激。
Stack class:
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));
}
}
}
答案 0 :(得分: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++;
}
...
你定义了一个size = 1的字符串数组,但是如果x超出了这个数组的边界,你就不会在循环内部进行检查。
这样想一下:
int Size = // define the size..;
String[] lines = new String[Size];
...
while (x < Size && (s = buffReader.readLine()) != null)) {
lines[x] = s;
x++;
}
当你的x比较大,那么x < Size
将评估为false,从而退出循环。
关于您遇到的一个错误 ArrayIndexOutOfBoundsException :
抛出表示已使用非法访问数组 指数。该指数为负数或大于或等于 数组的大小。 (source)
另一个错误 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));
}
您必须将s
而不是lines
传递给方法infixToRPN
,这就是为什么您获得相同的输出,因为您提供相同的输入。
请记住,infixToRPN
收到的String []
不是像's'这样的字符串,但我留给您找一个解决方法。