使用Java通过堆栈(LinkedList)实现的表达式树如下,但是它存在错误:

huangapple go评论65阅读模式
英文:

Implemented expression tree as follows in java using stacks(LinkedList), but it has errors

问题

以下是你提供的内容的翻译:

我试图使用栈LinkedList来实现表达式树但在编译时出现了以下错误

注意ExpressionTree.java 使用了未经检查或不安全的操作
注意重新编译时使用 -Xlint:unchecked 以获取详细信息

import java.util.LinkedList;

public class ExpressionTree implements ExpressionTreeInterface{
    private ExpressionNode root;
    public ExpressionTree(String expression){
        LinkedList l = new LinkedList();
        String[] s = expression.split(" ");
        int i=0;
        for (String a:s){
            if (a == "0" || a == "1" || a == "2" || a == "3" ||a == "4" ||a == "5" ||
                    a == "6" ||a == "7" ||a == "8" ||a == "9"){
                int b = Integer.parseInt(a);
                ExpressionNode e = new ExpressionNode();
                e.operand(b);
                l.add(e);
            }
            else if (a == "*" || a == "/" || a == "+" || a == "-"){
                ExpressionNode e = new ExpressionNode();
                e.operator(a);
                e.right = (ExpressionNode)l.get(l.size()-1);
                e.left = (ExpressionNode)l.get(l.size()-2);
                l.remove(l.size()-1);
                l.remove(l.size()-2);
                l.add(e);
            }
        }
        root = (ExpressionNode)l.get(0);
    }
    public int eval(){
        return eval(root);
    }
    public int eval(ExpressionNode r){
        if (r.left!=null && r.right!=null){
            if (r.getOperator() == "+"){
                return eval(r.left) + eval(r.right);
            } else if (r.operator == "*"){
                return eval(r.left) * eval(r.right);
            } else if (r.operator == "/"){
                return eval(r.left) / eval(r.right);
            } else {
                return eval(r.left) - eval(r.right);
            }
        } else {
            return r.getOperand();
            }
                        
        }
    private static class ExpressionNode{
        int operand;
        String operator;
        ExpressionNode left;
        ExpressionNode right;
        public void operator(String operator){
            this.operator = operator;
        }
        public void operand(int operand){
            this.operand = operand;
        }
        public String getOperator(){
            return operator;
        }
        public int getOperand(){
            return operand;
        }
    }
    public String postfix(){
        return postfix(root).trim();
    }
    private String postfix(ExpressionNode s){
        if (s.left == null && s.right == null){
            return Integer.toString(s.getOperand());
        } else{
            return postfix(s.left) + " " + postfix(s.right) + " " + s.getOperator();
        }
    }
    public String prefix(){
        return prefix(root).trim();
    }
    private String prefix(ExpressionNode s){
        if (s.left == null && s.right == null){
            return Integer.toString(s.getOperand());
        } else{
            return s.getOperator() + " " + prefix(s.left) + " " + prefix(s.right);
        }
    }
    public String infix(){
        return infix(root).trim();
    }
    private String infix(ExpressionNode s){
        if (s.left == null && s.right == null){
            return Integer.toString(s.getOperand());
        } else{
            return infix(s.left) + " " + s.getOperator() + " " + infix(s.right);
        }  
    }
}

另外,我创建了以下的测试类,但同样出现了以下错误。

在 java.util.LinkedList.checkElementIndex(LinkedList.java:555) 处出现错误
在 java.util.LinkedList.get(LinkedList.java:476) 处出现错误
在 ExpressionTree.<init>(ExpressionTree.java:27) 处出现错误
在 Testfile.main(Testfile.java:4) 处出现错误
public class Testfile {
    public static void main(String[] args){
        String a = "34 2 - 5 *";
        ExpressionTree s = new ExpressionTree(a);
        System.out.println(s.eval());
    }
}

我在哪里做错了?我觉得我使用了很多递归,所以可能是从那里出了问题,但我无法找出错误所在。

英文:

I was trying to implement expression tree by using stacks(LinkedList) and I have the following error when I compile it.

Note: ExpressionTree.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
import java.util.LinkedList;
public class ExpressionTree implements ExpressionTreeInterface{
private ExpressionNode root;
public ExpressionTree(String expression){
LinkedList l = new LinkedList();
String[] s = expression.split(&quot; &quot;);
int i=0;
for (String a:s){
if (a == &quot;0&quot; || a == &quot;1&quot; || a == &quot;2&quot; || a == &quot;3&quot; ||a == &quot;4&quot; ||a == &quot;5&quot; ||
a == &quot;6&quot; ||a == &quot;7&quot; ||a == &quot;8&quot; ||a == &quot;9&quot;){
int b = Integer.parseInt(a);
ExpressionNode e = new ExpressionNode();
e.operand(b);
l.add(e);
}
else if (a == &quot;*&quot; || a == &quot;/&quot; || a == &quot;+&quot; || a == &quot;-&quot;){
ExpressionNode e = new ExpressionNode();
e.operator(a);
e.right = (ExpressionNode)l.get(l.size()-1);
e.left = (ExpressionNode)l.get(l.size()-2);
l.remove(l.size()-1);
l.remove(l.size()-2);
l.add(e);
}
}
root = (ExpressionNode)l.get(0);
}
public int eval(){
return eval(root);
}
public int eval(ExpressionNode r){
if (r.left!=null &amp;&amp; r.right!=null){
if (r.getOperator() == &quot;+&quot;){
return eval(r.left) + eval(r.right);
} else if (r.operator == &quot;*&quot;){
return eval(r.left) * eval(r.right);
} else if (r.operator == &quot;/&quot;){
return eval(r.left) / eval(r.right);
} else {
return eval(r.left) - eval(r.right);
}
} else {
return r.getOperand();
}
}
private static class ExpressionNode{
int operand;
String operator;
ExpressionNode left;
ExpressionNode right;
public void operator(String operator){
this.operator = operator;
}
public void operand(int operand){
this.operand = operand;
}
public String getOperator(){
return operator;
}
public int getOperand(){
return operand;
}
}
public String postfix(){
return postfix(root).trim();
}
private String postfix(ExpressionNode s){
if (s.left == null &amp;&amp; s.right == null){
return Integer.toString(s.getOperand());
} else{
return postfix(s.left) + &quot; &quot; + postfix(s.right) + &quot; &quot; + s.getOperator();
}
}
public String prefix(){
return prefix(root).trim();
}
private String prefix(ExpressionNode s){
if (s.left == null &amp;&amp; s.right == null){
return Integer.toString(s.getOperand());
} else{
return s.getOperator() + &quot; &quot; + prefix(s.left) + &quot; &quot; + prefix(s.right);
}
}
public String infix(){
return infix(root).trim();
}
private String infix(ExpressionNode s){
if (s.left == null &amp;&amp; s.right == null){
return Integer.toString(s.getOperand());
} else{
return infix(s.left) + &quot; &quot; + s.getOperator() + &quot; &quot; + infix(s.right);
}  
}
}

Also, I created the following test class but it again has the following error.

at java.util.LinkedList.checkElementIndex(LinkedList.java:555)
at java.util.LinkedList.get(LinkedList.java:476)
at ExpressionTree.&lt;init&gt;(ExpressionTree.java:27)
at Testfile.main(Testfile.java:4)
public class Testfile {
public static void main(String[] args){
String a = &quot;34 2 - 5 *&quot;;
ExpressionTree s = new ExpressionTree(a);
System.out.println(s.eval());
}
}

Where did I do wrong? I think I used a lot of recursion, so maybe there was a mistake from there, but I cannot figure out where.

答案1

得分: 1

在你的代码中存在几个问题:

第一个问题是:在Java中,你不能使用==运算符来比较字符串,你需要使用像.equals()这样的函数来比较两个字符串的值。所以,这部分代码:

if (a == "0" || a == "1" || a == "2" || a == "3" ||a == "4" ||a == "5" ||
                a == "6" ||a == "7" ||a == "8" ||a == "9")

需要改成:

if (a.equals("0")|| a.equals("1") ||a.equals("2") || a.equals("3") ||a.equals("4") ||a.equals("5") ||
                a.equals("6") ||a.equals("7") ||a.equals("8") ||a.equals("9"))

同样,这部分代码也需要做相同的更改:

else if (a == "*" || a == "/" || a == "+" || a == "-")

你需要在这里使用.equals函数。

eval函数的这部分也有相同的问题:

if (r.left!=null && r.right!=null){
    if (r.getOperator() == "+"){
        return eval(r.left) + eval(r.right);
    } else if (r.operator == "*"){
        return eval(r.left) * eval(r.right);
    } else if (r.operator == "/"){
        return eval(r.left) / eval(r.right);
    } else {
        return eval(r.left) - eval(r.right);
    }
} else {
    return r.getOperand();
}

第二个问题是:在输入的expression字符串("34 2 - 5 *")中,有一个字符串是34,但它不会满足这个条件:

if (a == "0" || a == "1" || a == "2" || a == "3" ||a == "4" ||a == "5" ||
                a == "6" ||a == "7" ||a == "8" ||a == "9")

所以,不要通过这种方式检查字符串是否为数字,你可以创建一个辅助函数来执行相同的操作,像这样,并调用该函数:

private boolean checkStringIsNumber(String s) {
    boolean numeric = true;

    try {
        Integer num = Integer.parseInt(s);
    } catch (NumberFormatException e) {
        numeric = false;
    }
    return numeric;
}

第三个问题是:在这两行代码中:

l.remove(l.size()-1);
l.remove(l.size()-2);

假设你的链表在这一点上有两个节点,即l1l2。执行第一条语句后:

l.remove(l.size()-1);

更新后的链表将只包含一个节点,即l1。现在如果你执行这条语句:

l.remove(l.size()-2);

它会抛出异常,因为链表的大小现在是1,l.size()-2将返回-1,这是无效的索引。

所以,我猜想你想要删除最后两个节点,所以你可以用这两条语句替代:

l.remove(l.size()-1);
l.remove(l.size()-1);

解决了所有这些问题后,ExpressionTree构造函数的更新代码如下

public ExpressionTree(String expression){
    LinkedList l = new LinkedList();
    String[] s = expression.split(" ");
    int i=0;
    for (String a:s){
        if (checkStringIsNumber(a)){
            int b = Integer.parseInt(a);
            ExpressionNode e = new ExpressionNode();
            e.operand(b);
            l.add(e);
        }
        else if (a.equals("*") || a.equals("/") || a.equals("+") || a.equals("-")){
            ExpressionNode e = new ExpressionNode();
            e.operator(a);
            e.right = (ExpressionNode)l.get(l.size()-1);
            e.left = (ExpressionNode)l.get(l.size()-2);
            l.remove(l.size()-1);
            l.remove(l.size()-1);
            l.add(e);
        }
    }
    root = (ExpressionNode)l.get(0);
}

eval函数的更新代码如下

public int eval(ExpressionNode r){
    if (r.left!=null && r.right!=null){
        if (r.getOperator().equals("+")){
            return eval(r.left) + eval(r.right);
        } else if (r.operator.equals("*")){
            return eval(r.left) * eval(r.right);
        } else if (r.operator.equals("/")){
            return eval(r.left) / eval(r.right);
        } else {
            return eval(r.left) - eval(r.right);
        }
    } else {
        return r.getOperand();
    }
}

经过这些更改,上述表达式字符串将正常工作,并且给出结果为160。

英文:

There are few issues in your code :

First issue is You can't compare string in java using == operators you need can use function like .equals() to compare two string values. So, this code fragement :

if (a == &quot;0&quot; || a == &quot;1&quot; || a == &quot;2&quot; || a == &quot;3&quot; ||a == &quot;4&quot; ||a == &quot;5&quot; ||
a == &quot;6&quot; ||a == &quot;7&quot; ||a == &quot;8&quot; ||a == &quot;9&quot;)

gets changed to :

 if (a.equals(&quot;0&quot;)|| a.equals(&quot;1&quot;) ||a.equals(&quot;2&quot;) || a.equals(&quot;3&quot;) ||a.equals(&quot;4&quot;) ||a.equals(&quot;5&quot;) ||
a.equals(&quot;6&quot;) ||a.equals(&quot;7&quot;) ||a.equals(&quot;8&quot;) ||a.equals(&quot;9&quot;))

same goes with this part of code fragment :

else if (a == &quot;*&quot; || a == &quot;/&quot; || a == &quot;+&quot; || a == &quot;-&quot;)

you need to use .equals function in this as well.

Same issue is there in eval function as well in this part :

if (r.left!=null &amp;&amp; r.right!=null){
if (r.getOperator() == &quot;+&quot;){
return eval(r.left) + eval(r.right);
} else if (r.operator == &quot;*&quot;){
return eval(r.left) * eval(r.right);
} else if (r.operator == &quot;/&quot;){
return eval(r.left) / eval(r.right);
} else {
return eval(r.left) - eval(r.right);
}
} else {
return r.getOperand();
}

Second issue is in input expression string ("34 2 - 5 *") one of the string is 34 but it wont satisfy this condition :

  if (a == &quot;0&quot; || a == &quot;1&quot; || a == &quot;2&quot; || a == &quot;3&quot; ||a == &quot;4&quot; ||a == &quot;5&quot; ||
a == &quot;6&quot; ||a == &quot;7&quot; ||a == &quot;8&quot; ||a == &quot;9&quot;)

So, instead of checking whether your string is number or not by this way you can create helper function to do the same like this and call the same :

 private boolean checkStringIsNumber(String s) {
boolean numeric = true;
try {
Integer num = Integer.parseInt(s);
} catch (NumberFormatException e) {
numeric = false;
}
return numeric;
}

Third issue is in these two lines :

 l.remove(l.size()-1);
l.remove(l.size()-2);

Suppose your link list has two node at this point . After l1, l2. After executing first statement

l.remove(l.size()-1);

updated link list will contain one node i.e. l1. Now if you execute this statement

 l.remove(l.size()-2);

It will throw exception as link list size is now 1 and l.size()-2 will return in -1 which is invalid index;

So, I suppose you want to remove last 2 nodes so you can do instead of these two statements this :

 l.remove(l.size()-1);
l.remove(l.size()-1);

So, after resolving all these issues , updated code of ExpressionTree constructor is :

 public ExpressionTree(String expression){
LinkedList l = new LinkedList();
String[] s = expression.split(&quot; &quot;);
int i=0;
for (String a:s){
if (checkStringIsNumber(a)){
int b = Integer.parseInt(a);
ExpressionNode e = new ExpressionNode();
e.operand(b);
l.add(e);
}
else if (a.equals(&quot;*&quot;) || a.equals(&quot;/&quot;) || a.equals(&quot;+&quot;) || a.equals(&quot;-&quot;)){
ExpressionNode e = new ExpressionNode();
e.operator(a);
e.right = (ExpressionNode)l.get(l.size()-1);
e.left = (ExpressionNode)l.get(l.size()-2);
l.remove(l.size()-1);
l.remove(l.size()-1);
l.add(e);
}
}
root = (ExpressionNode)l.get(0);
}

and updated code of eval function is :

 public int eval(ExpressionNode r){
if (r.left!=null &amp;&amp; r.right!=null){
if (r.getOperator().equals(&quot;+&quot;)){
return eval(r.left) + eval(r.right);
} else if (r.operator.equals(&quot;*&quot;)){
return eval(r.left) * eval(r.right);
} else if (r.operator.equals(&quot;/&quot;)){
return eval(r.left) / eval(r.right);
} else {
return eval(r.left) - eval(r.right);
}
} else {
return r.getOperand();
}
}

After making these changes above expression string works fine and gives result as 160.

huangapple
  • 本文由 发表于 2020年4月9日 16:59:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/61117457.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定