您的位置:首页 > 其它

简单的表达式计算

2016-05-14 19:25 351 查看
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;

public class count {
public static void main(String[] args) {
System.out.println("输入表达式");

Scanner in = new Scanner(System.in);

//输入的表达式
String expression = in.nextLine();

if(expression.length() < 1){
System.out.println("^-^");
}

else {

try{
System.out.println(solve(expression));
}
catch(Exception e){
System.out.println("对于你的表达式我无能为力:(");
}
}
}

/**
* 分解表达式,求解
* 情况:1.为空格 不管
*     2.+或- 判断前面有没有其他等待计算操作/+-*都可以
*     3.*或/ 判断前面有没有*或/的操作
*     4.括号 遇到反括号再去找前面的括号
*     5.操作数字 直接存了
*
* @param expression 表达式
* @return 计算结果
*/
private static int solve(String expression) {
//存数字的栈,操作数
Stack<Integer> operand = new Stack<Integer>();

//存操作符的栈
Stack<Character> operator = new Stack<Character>();

//分解表达式,把数字和操作符分开
//第一个参数:需要操作的字符串
//第二个参数:以什么为标准分割
//第三个参数:要不要保存作为分割标准的元素,在分割后结果里仍然保存
StringTokenizer tokens = new StringTokenizer(expression, "()+-*/", true);

while (tokens.hasMoreElements()) {
//.trim()方法是为了去除字符串前后的空格,因为不能以空格为分割标准然后保存空格
String thisToken = tokens.nextToken().trim();

//空格
if(thisToken.length() == 0){
//System.out.println("空格");
continue;
}

//是+或—(优先级要比*或/要低)
else if(thisToken.charAt(0) == '+' || thisToken.charAt(0) == '-'){
//System.out.println("是操作符  : "+thisToken.charAt(0));

//看它之前有没有等待着的操作
while (!operator.isEmpty()){
if(operator.peek() == '+' ||operator.peek() == '-' ||
operator.peek() == '*' ||operator.peek() == '/' ) {
//计算
calculate(operand,operator);
//System.out.println(operand.peek() + "  这次计算结果");
}
else{
break;
}
}

//把这次的操作符放栈里
//System.out.println("把这次的操作符放栈里  : "+thisToken);
operator.push(thisToken.charAt(0));
}

//是*或/
else if(thisToken.charAt(0) == '*' || thisToken.charAt(0) == '/'){
//System.out.println("是操作符  : "+thisToken.charAt(0));

while (!operator.isEmpty()){
if(operator.peek() == '*' || operator.peek() == '/' ) {
//计算
calculate(operand,operator);
//System.out.println(operand.peek() + ":  这次计算结果");
}
else {
break;
}
}

//把这次的操作符放栈里
//System.out.println("把这次的操作符放栈里  : "+thisToken.charAt(0));
operator.push(thisToken.charAt(0));
}

else if (thisToken.trim().charAt(0) == '(') {
//System.out.println("是(");
operator.push('(');
}
//反括号来啦,我们去找另一半括号^-^
else if (thisToken.trim().charAt(0) == ')') {
//System.out.println("是)");
while (operator.peek() != '(') {
//计算
calculate(operand, operator);
//System.out.println(operand.peek() + " :  这次计算结果");
}
//去除'('
operator.pop();
}
//是操作数
else {
//System.out.println("是操作数  : "+thisToken);
operand.push(new Integer(thisToken));
}
}

while(!operator.empty()){
calculate(operand, operator);
}

return operand.pop();
}

/**
* 去除操作符和操作数直接计算
* @param operand 存操作数的栈
* @param operator 存操作符的栈
*/
private static void calculate(Stack<Integer> operand,
Stack<Character> operator) {

char symbol = operator.pop();//去出并删除栈顶的操作符
int num1 = operand.pop();
int num2 = operand.pop();

//注:表达式中先被读取的数字后被读出
if(symbol == '+'){
operand.push(num2 + num1);
}
else if(symbol == '-'){
operand.push(num2 - num1);
}
else if(symbol == '*'){
operand.push(num2 * num1);
}
else if(symbol == '/'){
if(num1 != 0)
operand.push(num2 / num1);
else{
System.out.println("似乎要报错了……除数不能为0");
}
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: