Day2 coding one Dijkstra双栈计算求值算法

需求:计算算术表达式的值,例如:
1 + 2 + 3 4 5 (1+((2+3)*(4*5)))
解决方法: Dijkstra 用两个栈(一个是保存运算符,一个用于保存操作数)
流程:

算术表达式由括号、运算符和操作数组成。我们根据以下4种情况来实现。
1、将操作数压入操作数栈
2、将运算符压入运算符栈
3、忽略左括号
4、在遇到右括号时,弹出一个运算符,弹出所需数量的操作数,并将运算符和操作数的运算结果压入操作数栈。

算法实现轨迹:
Dijkstra的双栈算术表达式求值算法的轨迹

代码实现如下:

import java.util.Stack;//Dijkstra的双栈算术表达式求值
public class Evaluate {

	public static void main(String[] args) {
		Stack<Character>ops = new Stack<Character>();//运算符下压栈
		Stack<Double> vals = new Stack<Double>();//操作数下压栈
		String str  = "(1+((2+3)*(4*5)))";
		String str1 = "((1+sqrt(5.0))/2.0)";
		char[] arr = str.toCharArray();
		for (char c : arr) {
			if(c=='(') ;
			else if(c=='+') {
				ops.push(c);
			}
			else if(c=='-') {
				ops.push(c);
			}
			else if(c=='*') {
				ops.push(c);
			}
			else if(c=='/') {
				ops.push(c);
			}
			else if((c+"").equals("sqrt")) {
				ops.push(c);
			}
			else if(c==')') {
				char op = ops.pop();
				double v = vals.pop();
				if(op=='+') {
					v = vals.pop()+v;
				}
				else if(op=='-') {
					v = vals.pop()-v;
				}
				else if(op=='*') {
					v = vals.pop()*v;
				}
				else if(op=='/') {
					v = vals.pop()/v;
				}
				else if((op+"").equals("sqrt")) {
					v = Math.sqrt(v);
				}
				vals.push(v);
			}
			else {
				vals.push(Double.parseDouble(c+""));
			}	
		}
		System.out.println(vals.pop());
	} 
}

案例通过如下: S t r i n g s t r = &quot; ( 1 + ( ( 2 + 3 ) ( 4 5 ) ) ) &quot; String str = &quot;(1+((2+3)*(4*5)))&quot; ;
在这里插入图片描述

但是若字符串输入改为String str1 = “((1+sqrt(5.0))/2.0)”;
在这里插入图片描述
在这里插入图片描述
若字符串中出现“sqrt”,挨个读取字符遇到s就直接判断,所以出问题!将代码改为如下情况,则可以得到正确结果

import java.util.Stack;//Dijkstra的双栈算术表达式求值

public class Evaluate {

	public static void main(String[] args) {
		Stack<String>ops = new Stack<String>();//运算符下压栈
		Stack<Double> vals = new Stack<Double>();//操作数下压栈
		String s1  = "( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) )";
		String s  = "( ( 1 + sqrt ( 5.0 ) ) / 2.0 )";
		String[] str = s.split(" ");
		for (int i = 0; i < str.length; i++) {
			if(str[i].equals("(")) ;
			else if(str[i].equals("+")) {
				ops.push(str[i]);
			}
			else if(str[i].equals("-")) {
				ops.push(str[i]);
			}
			else if(str[i].equals("*")) {
				ops.push(str[i]);
			}
			else if(str[i].equals("/")) {
				ops.push(str[i]);
			}
			else if(str[i].equals("sqrt")) {
				ops.push(str[i]);
			}
			else if(str[i].equals(")")) {
				String op = ops.pop();
				double v = vals.pop();
				if(op.equals("+")) {
					v = vals.pop()+v;
				}
				else if(op.equals("-")) {
					v = vals.pop()-v;
				}
				else if(op.equals("*")) {
					v = vals.pop()*v;
				}
				else if(op.equals("/")) {
					v = vals.pop()/v;
				}
				else if(op.equals("sqrt")) {
					v = Math.sqrt(v);
				}
				vals.push(v);
		    }
			else {
				vals.push(Double.parseDouble(str[i]));
			}	
		}
		System.out.println(vals.pop());
	} 
}

在这里插入图片描述为了解决sqrt的问题,我们先对字符串进行spilt然后比较字符串的大小,注意要使用equals方法,这里若使用==,则出问题

猜你喜欢

转载自blog.csdn.net/weixin_43192732/article/details/83997265