Java 二叉树的递归求值
我有一个二叉树,外部节点包含整数,内部节点包含运算符Java 二叉树的递归求值,java,data-structures,tree,Java,Data Structures,Tree,我有一个二叉树,外部节点包含整数,内部节点包含运算符我将树的根节点发送到evaluateTree方法 我想遍历这棵树并计算最终结果 节点类的字段是 private Node left; private Node right; char value; 例如,我想计算(2+5)/8-(21+3)应该等于-23(四舍五入)7/8-5=>0-5=-5。21+3=>2+3=5也是如此。这只是我的假设。粘贴代码以显示如何创建此类表达式的节点时,我们可以验证相同的情况。要创建叶节点,您需要通过执行字符串te
我将树的根节点发送到evaluateTree方法
我想遍历这棵树并计算最终结果
节点类的字段是
private Node left;
private Node right;
char value;
例如,我想计算(2+5)/8-(21+3)应该等于-23(四舍五入)<当我尝试这样做时,结果是-5。与舍入无关,当我尝试计算21+3时,结果是5。任何指导都将不胜感激
int evaluateTree(Node node)
{
System.out.println("Inside evaluateTree");
if (Character.isDigit(node.value))
{
return Character.getNumericValue(node.value);
}
else
{
int operand1 = evaluateTree(node.left);
int operand2 = evaluateTree(node.right);
switch (node.value)
{
case '+':
return (int) Math.round(operand1 + operand2);
case '-':
return (int) Math.round(operand1 - operand2);
case '*':
return (int) Math.round(operand1 * operand2);
case '/':
return (int) Math.round(operand1 / operand2);
default:
throw new IllegalStateException("Unexpected value: " + node.value);
}
}
}
这就是我创建树的方式
public void createTree()
{
Scanner keyboardInput = new Scanner(System.in);
ArrayList<String> postFixArray = new ArrayList<>();
postFixArray = getPostFixString("(21+3)");
System.out.println("\nCREATE TREE PRINTING\n");
System.out.println(postFixArray);
Stack<Node> nodeStack = new Stack<>();
while (!postFixArray.isEmpty())
{
String temp = postFixArray.get(0);
char charTemp = temp.charAt(0);
if (!isOperator(charTemp))
{
if (!Character.isDigit(charTemp))
{
System.out.println("Enter the integer value for your variable " + charTemp + ": ");
int setVarValue = keyboardInput.nextInt();
for (int i = 0; i < postFixArray.size(); i++)
{
if (charTemp == postFixArray.get(i).charAt(0))
{
postFixArray.set(i, String.valueOf(setVarValue));
}
}
}
String tempLink = postFixArray.remove(0);
char nodeData = tempLink.charAt(0);
Node leaf = new Node(nodeData);
nodeStack.push(leaf);
}
else
{
if (nodeStack.size() >= 1)
{
String tempLink = postFixArray.remove(0);
char nodeData = tempLink.charAt(0);
Node leaf = new Node(nodeData);
leaf.right = nodeStack.pop();
leaf.left = nodeStack.pop();
nodeStack.push(leaf);
}
}
}
Node root = nodeStack.pop();
System.out.println(root);
System.out.println(evaluateTree(root));
}
public void createTree()
{
扫描仪键盘输入=新扫描仪(System.in);
ArrayList postFixArray=新的ArrayList();
postFixArray=getPostFixString(“(21+3)”);
System.out.println(“\n创建树打印\n”);
System.out.println(postfix数组);
堆栈节点堆栈=新堆栈();
而(!postFixArray.isEmpty())
{
String temp=postFixArray.get(0);
char charTemp=温度字符(0);
如果(!等参器(charTemp))
{
如果(!Character.isDigit(charTemp))
{
System.out.println(“为变量“+charTemp+”:”)输入整数值;
int setVarValue=keyboardInput.nextInt();
对于(int i=0;i=1)
{
String tempLink=postFixArray.remove(0);
char nodeData=tempLink.charAt(0);
节点叶=新节点(节点数据);
leaf.right=nodeStack.pop();
leaf.left=nodeStack.pop();
nodeStack.推(叶);
}
}
}
Node root=nodeStack.pop();
System.out.println(根);
System.out.println(evaluateTree(root));
}
要对返回的值进行四舍五入,可以将evaluateTree
的返回类型更改为Double
,然后使用Math.round对值进行四舍五入,这将返回一个int值
以下是函数evaluateTree
的更新代码:
public static Double evaluateTree(Node node)
{
System.out.println("Inside evaluateTree");
if (Character.isDigit(node.value))
{
return (double)Character.getNumericValue(node.value);
}
else
{
double operand1 = evaluateTree(node.left);
double operand2 = evaluateTree(node.right);
switch (node.value)
{
case '+':
return operand1 + operand2;
case '-':
return operand1 - operand2;
case '*':
return operand1 * operand2;
case '/':
return operand1 / operand2;
default:
throw new IllegalStateException("Unexpected value: " + node.value);
}
}
}
最后,无论您在哪里调用此方法,都可以将其值返回为
Math.round(evaluateTree(root))
四舍五入
要对值进行舍入,只需在switch语句的返回中添加一个舍入函数。您应该将除法转换为双精度
或浮点
,因为如果您不这样做,它将被四舍五入
switch (node.value)
{
case '+':
return round(operand1 + operand2);
case '-':
return round(operand1 - operand2);
case '*':
return round(operand1 * operand2);
case '/':
return round((float) operand1 / operand2);
default:
throw new IllegalStateException("Unexpected value: " + node.value);
}
-
为了验证是否有一个包含多个数字的整数,您可能应该使用正则表达式,但这个问题应该有自己的专用问题
编辑:
我创建了一些没有树创建方法的测试用例来测试这堆代码是否正常工作。它通过了以下测试:
// 21/3 = 7
public static void testCaseOne() {
Node three = new Node(null, null, '3');
Node nine = new Node(null, null, '9');
Node nine2 = new Node(null, null, '9');
Node three2 = new Node(null, null, '3');
Node plus3 = new Node(nine, three, '+');
Node plus2 = new Node(nine2, plus3, '+');
Node plus = new Node(plus2, three2, '/');
System.out.println("PASSED: " + (evaluateTree(plus) == 7) + " " + evaluateTree(plus));
}
// 21+3 = 24
public static void testCaseTwo() {
Node three = new Node(null, null, '3');
Node nine = new Node(null, null, '9');
Node nine2 = new Node(null, null, '9');
Node three2 = new Node(null, null, '3');
Node plus3 = new Node(nine, three, '+');
Node plus2 = new Node(nine2, plus3, '+');
Node plus = new Node(plus2, three2, '+');
System.out.println("PASSED: " + (evaluateTree(plus) == 24) + " " + evaluateTree(plus));
}
// 9/9/3/3 = 1
public static void testCaseThree() {
Node three = new Node(null, null, '3');
Node nine = new Node(null, null, '9');
Node nine2 = new Node(null, null, '9');
Node three2 = new Node(null, null, '3');
Node plus3 = new Node(nine, three, '/');
Node plus2 = new Node(nine2, plus3, '/');
Node plus = new Node(plus2, three2, '/');
System.out.println("PASSED: " + (evaluateTree(plus) == 1) + " " + evaluateTree(plus));
}
// 21/2 = 10.5 = 11
public static void testCaseFour() {
Node three = new Node(null, null, '3');
Node nine = new Node(null, null, '9');
Node nine2 = new Node(null, null, '9');
Node two = new Node(null, null, '2');
Node plus3 = new Node(nine, three, '+');
Node plus2 = new Node(nine2, plus3, '+');
Node plus = new Node(plus2, two, '/');
System.out.println("PASSED: " + (evaluateTree(plus) == 11) + " " + evaluateTree(plus));
}
// 22/3 = 7.33 = 7
public static void testCaseFive() {
Node four = new Node(null, null, '4');
Node nine = new Node(null, null, '9');
Node nine2 = new Node(null, null, '9');
Node three2 = new Node(null, null, '3');
Node plus3 = new Node(nine, four, '+');
Node plus2 = new Node(nine2, plus3, '+');
Node plus = new Node(plus2, three2, '/');
System.out.println("PASSED: " + (evaluateTree(plus) == 7) + " " + evaluateTree(plus));
}
验证
要进一步添加验证输入,您可以执行以下操作:
String regexExpression = "([()\\-+/0-9]+)?\\d{2}([()\\-+/0-9]+)?";
String str = "(2+5)/8-(21+3)";
boolean containsLongInts = str.matches(regexExpression);
System.out.println(str + " contains long ints: " + containsLongInts);
String str2 = "(2+5)/8-(2+3)";
boolean containsLongInts2 = str2.matches(regexExpression);
System.out.println(str2 + " contains long ints: " + containsLongInts2);
例如,它不起作用。我试过使用2+5,效果很好。是的,就像@PrernaGupta说的,要么你没有打印返回值,要么你的树结构不正确。是的,老实说,我忘记打印返回值了。但在意识到这个错误后,我确实改变了这个问题。你上面提到的例子,((2+5)/7-(21+3))是否在上面的代码中工作。因为在您的节点中,您将值作为char,但21不是char值,它将给出错误。@PrernaGupta如何处理它?谢谢。但是,与舍入无关,当我尝试计算21+3时,得到的结果是5。您能否分享如何为上述表达式创建节点的代码,因为我不确定如何将21添加到节点值字段中,因为它是char。我假设您以任何方式将值添加到节点中的值字段中,它只需要第一个字符。例如,你们提到的(2+5)/8-(21+3)的结果是-5,因为从21开始只需要2。因此,它转移到(2+5)/8-(2+3)=>7/8-5=>0-5=-5。21+3=>2+3=5也是如此。这只是我的假设。粘贴代码以显示如何创建此类表达式的节点时,我们可以验证相同的情况。要创建叶节点,您需要通过执行字符串tempLink=postFixArray.remove(0)来计算叶节点的值;char nodeData=tempLink.charAt(0);。现在假设postFixArray.charAt(0)的值是24,然后您正在执行“24”.charAt(0),结果是2,您的叶节点创建时的值是2而不是24。所以,和我在上面的评论中提到的一样,您正在通过提取字符串的第一个字符值来创建digit节点,而不是使用整个字符串,因为它可以很好地用于0-9,但在此之后只使用第一个字符。。
String regexExpression = "([()\\-+/0-9]+)?\\d{2}([()\\-+/0-9]+)?";
String str = "(2+5)/8-(21+3)";
boolean containsLongInts = str.matches(regexExpression);
System.out.println(str + " contains long ints: " + containsLongInts);
String str2 = "(2+5)/8-(2+3)";
boolean containsLongInts2 = str2.matches(regexExpression);
System.out.println(str2 + " contains long ints: " + containsLongInts2);