英文:
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(" ");
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);
}
}
}
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.<init>(ExpressionTree.java:27)
at 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());
}
}
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);
假设你的链表在这一点上有两个节点,即l1
和l2
。执行第一条语句后:
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 == "0" || a == "1" || a == "2" || a == "3" ||a == "4" ||a == "5" ||
a == "6" ||a == "7" ||a == "8" ||a == "9")
gets changed to :
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"))
same goes with this part of code fragment :
else if (a == "*" || a == "/" || a == "+" || a == "-")
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 && 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();
}
Second issue is in input expression
string ("34 2 - 5 *") one of the string is 34
but it wont satisfy this condition :
if (a == "0" || a == "1" || a == "2" || a == "3" ||a == "4" ||a == "5" ||
a == "6" ||a == "7" ||a == "8" ||a == "9")
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(" ");
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);
}
and updated code of eval function is :
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();
}
}
After making these changes above expression string works fine and gives result as 160.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论