我编写了这个程序,它将采用中缀符号表达式并从中构建二叉树。现在,实际工作的唯一输入表达式就像2 + 2.我似乎无法弄清楚如何使它处理括号并采用更长的表达式,如((2 + 2)* 3)。对于我的输出,我试图把它变成后缀表示法,并评估表达式。所以现在如果我插入没有括号的2 + 2我的输出是22+并且它评估它所以它打印4。
我需要找到一种方法让它在每个数字和运算符之间用空格打印输出,并让它接受带括号的更长表达式。我现在不知道如何从这里继续。有人可以帮帮我吗?
谢谢!
这是我的代码:
class ExpressionEvaluator<T> {
ExpressionEvaluator() {
Scanner reader = new Scanner(System.in);
System.out.println("Enter your expression: ");
String expression = reader.nextLine(); // Reads the expression and trims the spaces.
expression = expression.replaceAll(" ", "");
ExpressTree<T> tree = new ExpressTree(expression); // Creates a new binary tree.
}
public static void main(String[] args) {
new ExpressionEvaluator();
}
}
interface Tree<T> {
// This is the tree interface with its methods.
public Node<T> getRoot();
public void setRoot(Node<T> value);
}
class ExpressTree<T> implements Tree<T> {
private Node<T> _root;
private String _value, _expression;
private Node<T> _treeNode;
private Stack storage1;
private Stack<String> storage2;
public ExpressTree(String expression) {
expressTreeBuilder(expression); // Calls the expressTreeBuilder method on the expression.
postfixTraversal(this.getRoot());
System.out.println("");
System.out.println(this.storage2.pop());
}
public Node<T> getRoot() { // Gets the root of the tree.
return _root;
}
public void setRoot(Node<T> _treeNode2) { // Sets the root which will always be an operator.
this._root = _treeNode2;
}
public boolean isDigit(char value) { // Method to check if a value is a digit or not.
if (Character.isDigit(value)) {
return true;
} else {
return false;
}
}
public void expressTreeBuilder(String expression) {
storage1 = new Stack(); // Stores the nodes.
storage2 = new Stack<String>(); // Stores the value of the nodes.
_treeNode = new Node(); // Creates a new node
_value = null;
String next = "";
for (int i = 0; i < expression.length(); i++) {
char traverse = expression.charAt(i);
if (i + 1 < expression.length()) {
next = Character.toString(expression.charAt(i + 1));
}
if (traverse == '+') { // This checks to see the expression is an addition operator.
Node<T> pop1, pop2; // It pops the first 2 values from the stack and stores them
String value1, value2; // in pop1 and pop2. Then it uses another stack to add them.
pop1 = (Node<T>) storage1.pop();
value1 = storage2.pop(); // Stores the right side value.
value2 = next; // Stores the left side value.
_treeNode = new Node();
_treeNode.setElement(Character.toString(traverse));
pop2 = new Node();
pop2.setElement(next);
pop1.setParent(_treeNode);
pop2.setParent(_treeNode);
_treeNode.setLeftSide(pop1); // Sets the right side of the subtree.
_treeNode.setRightSide(pop2); // Sets the left side of the subtree.
storage1.push(_treeNode);
storage1.push(pop2);
int add = (Integer.parseInt(value2) + Integer.parseInt(value1));
storage2.push(Integer.toString(add));
this.setRoot(_treeNode);
i++;
} else if (traverse == '-') { // This checks to see the expression is a subtraction operator.
Node<T> pop1, pop2; // It pops the first 2 values from the stack and stores them
String value1, value2; // in pop1 and pop2. Then it uses another stack to subtract them.
pop1 = (Node<T>) storage1.pop();
value1 = storage2.pop(); // Stores the right side value.
value2 = next; // Stores the left side value.
_treeNode = new Node();
_treeNode.setElement(Character.toString(traverse));
pop2 = new Node();
pop2.setElement(next);
pop1.setParent(_treeNode);
pop2.setParent(_treeNode);
_treeNode.setLeftSide(pop1); // Sets the right side of the subtree.
_treeNode.setRightSide(pop2); // Sets the left side of the subtree.
storage1.push(_treeNode);
storage1.push(pop2);
int subtract = (Integer.parseInt(value2) - Integer.parseInt(value1));
storage2.push(Integer.toString(subtract));
this.setRoot(_treeNode);
i++;
} else if (traverse == '*') { // This checks to see the expression is a multiplication operator.
Node<T> pop1, pop2; // It pops the first 2 values from the stack and stores them
String value1, value2; // in pop1 and pop2. Then it uses another stack to multiply them.
pop1 = (Node<T>) storage1.pop();
value1 = storage2.pop(); // Stores the right side value.
value2 = next; // Stores the left side value.
_treeNode = new Node();
_treeNode.setElement(Character.toString(traverse));
pop2 = new Node();
pop2.setElement(next);
pop1.setParent(_treeNode);
pop2.setParent(_treeNode);
_treeNode.setLeftSide(pop1); // Sets the right side of the subtree.
_treeNode.setRightSide(pop2); // Sets the left side of the subtree.
storage1.push(_treeNode);
storage1.push(pop2);
int multiply = (Integer.parseInt(value2) * Integer.parseInt(value1));
storage2.push(Integer.toString(multiply));
this.setRoot(_treeNode);
i++;
} else if (traverse == '(') {
} else {
_treeNode = new Node();
String digits = "";
while (i < expression.length() && isDigit(expression.charAt(i))) {
digits += expression.charAt(i); // Checks if the value found at the expression is digit
if (digits.length() == 1) {
break;
}
i++;
}
_treeNode.setElement(digits); // If it is it will set the element of the node
storage1.push(_treeNode); // The node will be pushed onto the stack.
storage2.push(digits); // This node will store it's value.
}
}
}
public void infixTraversal(Node<T> n) {
if (n != null) {
infixTraversal(n.getLeftSide());
System.out.print(n.element() + "");
infixTraversal(n.getRightSide());
}
}
public void postfixTraversal(Node<T> n) {
if (n != null) {
postfixTraversal(n.getLeftSide());
postfixTraversal(n.getRightSide());
System.out.print(n.element());
}
}
}
class Node<T> {
public Node<T> _left, _right, _parent;
private String _element;
public Node() {
this._element = null;
this._left = null;
this._right = null;
this._parent = null;
}
public String element() { // Gets the value of the node.
return _element;
}
public Node<T> getLeftSide() { // Gets the left side of the node.
return _left;
}
public Node<T> getRightSide() { // Gets the right side of the node.
return _right;
}
public Node<T> getParent() { // Gets the parent of the node.
return _parent;
}
public void setElement(String e) { // Sets the value of the node.
_element = e;
}
public void setLeftSide(Node<T> n) { // Sets the left side of the node.
_left = n;
}
public void setRightSide(Node<T> n) { // Sets the right side of the node.
_right = n;
}
public void setParent(Node<T> n) { // Sets the parent of the node.
_parent = n;
}
}
答案 0 :(得分:3)
您需要一个合适的算法来将中缀表达式转换为后缀表达式。一旦你在postfix中有了表达式,就可以很容易地构造一个解析树或直接评估表达式。经典算法是Shunting-yard algorithm,在维基百科上有相当详细的解释。
完成后缀算法后,您不再需要担心parathesis或operator优先级。它只是一堆价值观,弹出和推动结果。
答案 1 :(得分:0)
您的问题有几个不同的问题:
1)解析表达式并将其分解为树。你需要一个词法分析器(或标记器),即使是一个简单的,优先级,括号等等。
2)转换/评估你的树。有一些很好的经典算法。
3)打印结果(一旦你完成第二部分,我怀疑这很简单;只需要在正确的位置添加正确的空格和括号)。
我建议阅读一些关于所有这些的现有文章,比如说: