我正在制作一个计算器,它可以解决以非常原始的形式输入的计算。说:"3*52+11+3/2“我正在使用控制台,至少现在是这样。
这也将考虑到乘法和除法应该首先完成,所以2+3*4是14而不是20。
我希望有人看看是否有更有效的方法来做我正在做的事情,如果我没有做任何大的缺陷,或者在代码中有任何问题。此代码还假定用户输入有效文本,我将后者使其正确检查所有内容。
我试着尽可能地把所有事情都记录下来,这样就不需要太多的时间去理解逻辑了。
注意:我知道我的代码在输入负数时会崩溃,就像在-2+3中一样,而且现在还不支持十进制数。在执行这些建议方面提供任何帮助都是有益的。
package com.fowlron.calculator;
import java.util.ArrayList;
import java.util.Scanner;
public class Calculator {
private static ArrayList<Term> list = new ArrayList<Term>();
public static void main(String args[]) {
// Initial Info
System.out.println("+ for sum");
System.out.println("- for subtraction");
System.out.println("* for multiplication");
System.out.println("/ for division");
System.out.println("E.g. 2+5*3 outputs 17");
System.out.println("Input a calculation");
// Opening scanner, getting input and closing it
Scanner scan = new Scanner(System.in);
String s = scan.nextLine();
scan.close();
// Looping through all chars in the input
for (char c : s.toCharArray()) {
if (isCharNumber(c)) {
// Checking if the last character added was also a number
// Also checking if size > 0 to avoid ArrayIndexOutOfBounds
if (list.size() > 0
&& list.get(list.size() - 1).getType()
.equals(Term.Type.DOUBLE)) {
// If so multiply by ten and add the new one
list.get(list.size() - 1).setNum(
list.get(list.size() - 1).getNum() * 10
+ Character.getNumericValue(c));
} else {
// Otherwise, just add it regularly
list.add(new Term(Character.getNumericValue(c)));
}
} else {
// If it's not a number, it must be an operator, so just add it
// as a String
// Also check for whitespaces
if (!Character.isWhitespace(c)) {
list.add(new Term(Character.toString(c)));
}
}
}
// Calculating and outputting
double result = calculate(list);
System.out.println("The result is " + result);
}
private static boolean isCharNumber(char c) {
// Thought that since it is very long I might want to put this into it's
// own method
if (c == '0' || c == '1' || c == '2' || c == '3' || c == '4'
|| c == '5' || c == '6' || c == '7' || c == '8' || c == '9') {
return true;
} else {
return false;
}
}
private static double calculate(ArrayList<Term> l) {
// Creating a counter and a continue boolean
int c = 0;
boolean cont = true;
// This loop is used twice because multiplications and divisions
// have priority over sums and subtractions, so I need to first
// solve all the multiplications and divisions, and only then the
// others.
// For example, 2+3*4 = 2+12 = 14
// NOT 2+3*4 = 5*4 = 20
while (cont) {
// Checking if looped through all the elements
if (c >= l.size()) {
break;
}
// Checking if the current element is an operation
if (l.get(c).getType().equals(Term.Type.STRING)) {
// If so, check which it is, apply it to the previous element
// and remove the next one followed by the current one
Term p = l.get(c - 1);
Term n = l.get(c + 1);
switch (l.get(c).getOp()) {
case "*":
p.setNum(p.getNum() * n.getNum());
l.remove(c + 1);
l.remove(c);
c--;
break;
case "/":
p.setNum(p.getNum() / n.getNum());
l.remove(c + 1);
l.remove(c);
c--;
break;
}
}
// Increasing the counter
c++;
}
// Reseting the counter
c = 0;
while (true) {
// Same logic here
if (c >= l.size()) {
break;
}
// Exactly the same only just for the sums and subtractions
if (l.get(c).getType().equals(Term.Type.STRING)) {
Term p = l.get(c - 1);
Term n = l.get(c + 1);
switch (l.get(c).getOp()) {
case "+":
l.get(c - 1).setNum(p.getNum() + n.getNum());
break;
case "-":
l.get(c - 1).setNum(p.getNum() - n.getNum());
break;
}
l.remove(c + 1);
l.remove(c);
c--;
}
// Increasing the counter
c++;
}
// Returning the correct result
return l.get(0).getNum();
}
}班级一词:
package com.fowlron.calculator;
import java.util.ArrayList;
public class Term {
// I didn't know what to call this class, specially because I'm not english
// and didn't know a better name for it. It basically is a class that can
// hold eigter a String, a Double, or an ArrayList of itself.
// I make an ArrayList of these, so that I can then loop through it and
// solve the calculation. The fact it can hold an ArrayList of itself is so
// that when I implement things like "2*(2+3)" I can store 2+3 as another
// list, inside the main one. The I'd first find all the lists in the main
// list, and solve them. I might make the calculate method in the other
// class recursive for it to call itself, which in my head seems to work,
// and would help for parenthesis inside parenthesis.
private Type type;
private double i;
private String s;
private ArrayList<Term> al;
public Term(double i) {
this.i = i;
this.s = null;
this.al = null;
this.type = Type.DOUBLE;
}
public Term(String s) {
this.i = -1d;
this.s = s;
this.al = null;
this.type = Type.STRING;
}
public Term(ArrayList<Term> al) {
this.i = -1d;
this.s = null;
this.al = al;
this.type = Type.ARRAYLIST;
}
public String getOp() {
return s;
}
public double getNum() {
return i;
}
public ArrayList<Term> getPar() {
return al;
}
public void setOp(String s) {
this.i = -1d;
this.s = s;
this.al = null;
this.type = Type.STRING;
}
public void setNum(double i) {
this.i = i;
this.s = null;
this.al = null;
this.type = Type.DOUBLE;
}
public void setPar(ArrayList<Term> al) {
this.i = -1d;
this.s = null;
this.al = al;
this.type = Type.ARRAYLIST;
}
public Type getType() {
return type;
}
public enum Type {
DOUBLE, STRING, ARRAYLIST
}
}发布于 2015-01-15 00:52:00
我将首先回顾代码的较小部分,如果稍后有时间的话,我将深入研究逻辑.
isCharNumber()是多余的,因为已经存在Character.isDigit()。List<Term> list = new ArrayList<>()。https://codereview.stackexchange.com/questions/77552
复制相似问题