您的位置:首页 > 其它

acm_35表达式求值

2015-01-16 10:46 204 查看

表达式求值

时间限制:3000 ms
| 内存限制:65535
KB
难度:4

描述

ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧。

比如输入:“1+2/4=”,程序就输出1.50(结果保留两位小数)

输入
第一行输入一个整数n,共有n组测试数据(n<10)。

每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以“=”结束。这个表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。数据保证输入的操作数中不会出现负数。

数据保证除数不会为0
输出
每组都输出该组运算式的运算结果,输出结果保留两位小数。
样例输入

2
1.000+2/4=
((1+2)*5+1)/4=

样例输出

1.50
4.00

来源

数据结构课本例题改进
上传者

张云聪

基本上就是一个关于堆栈操作的问题, 遇到( 和数字
+ - 压栈, 遇到*/ 获取下一个数字
并从栈中取出一个数字获得结果然后压栈, 遇到)
一直出栈直到取出一个(

wa了 3次 错误主要是 在遇到)出栈时
需要注意+ - 号是按照从左到右计算的, 所以需要先用一个栈保存出栈结果,再通过出栈操作计算只含+
- 号的式子的值。 第二个错误是格式化字符串忘记换行符。

总的来说思路是 首先去除括号中式子的*
/ 使表达式能顺序计算, 然后计算括号中的只含+ -
的式子以去除括号,最后计算一个只包含+-号的式子得到结果。

import java.util.Scanner;

import java.util.Stack;

public class Compute {

public
static void main(String[] args) {

Compute com = new Compute();

com.solution();

}

public void
solution() {

Scanner in =
new Scanner(System.in);

int groups =
in.nextInt();

for (int i =
0; i < groups; i++) {

String instr
= in.next();

input =
instr.toCharArray();

double
result = getValue(0, input.length - 2);

System.out.printf("%.2f\n",result);

}

}

char[]
input;

//
获取表达式的值

private
double getValue(int start, int end) {

Stack stack
= new Stack();

for (int i =
start; i <=end; i++) {

switch
(input[i]) {

case
'(':

stack.push(new Node("Left"));

break;

case
'+':

stack.push(new Node("Add"));

break;

case
'-':

stack.push(new Node("Minus"));

break;

case
'*':

double
mulvalue = 0;

if (input[i
+ 1] == '(') {

mulvalue =
getValue(i + 1, getNextPL(i + 1));

i =
getNextPL(i + 1);

} else
{

mulvalue =
getNum(i + 1);

i =
getNextNotNum(i + 1) - 1;

}

double
mulnewvalue = stack.pop().val * mulvalue;

stack.push(new Node(mulnewvalue, "num"));

break;

case
'/':

double
divvalue = 0;

if (input[i
+ 1] == '(') {

divvalue =
getValue(i + 1, getNextPL(i + 1));

i =
getNextPL(i + 1);

} else
{

divvalue =
getNum(i + 1);

i =
getNextNotNum(i + 1) - 1;

}

double
divnewvalue = stack.pop().val / divvalue;

stack.push(new Node(divnewvalue, "num"));

break;

case
')':

Node
popnode;

double cache
= 0;

Stack
DescStack = new Stack();

while
(!(popnode = stack.pop()).type.equals("Left")) {

DescStack.push(popnode);

}

while(!DescStack.empty()){

popnode =
DescStack.pop();

if
(popnode.type.equals("num")) {

cache +=
popnode.val;

} else if
(popnode.type.equals("Add")) {

popnode
=DescStack.pop();

cache =
cache +popnode.val;

} else if
(popnode.type.equals("Minus")) {

popnode =
DescStack.pop();

cache =
cache- popnode.val ;

}

}

stack.push(new Node(cache, "num"));

break;

default:

double
numvalue;

numvalue =
getNum(i);

i =
getNextNotNum(i) - 1;

stack.push(new Node(numvalue, "num"));

break;

}

}

Node
resultnode;

double reval
= 0;

Stack
DescStack = new Stack();

while
(!stack.empty()) {

resultnode = stack.pop();

DescStack.push(resultnode);

}

while(!DescStack.empty()){

resultnode =
DescStack.pop();

if
(resultnode.type.equals("num")) {

reval +=
resultnode.val;

} else if
(resultnode.type.equals("Add")) {

resultnode =
DescStack.pop();

reval =
resultnode.val + reval;

} else if
(resultnode.type.equals("Minus")) {

resultnode =
DescStack.pop();

reval =
reval-resultnode.val;

}

}

return
reval;

}

//
返回下一个数

private
double getNum(int i) {

int pointer
= getNextNotNum(i);

double reval
=Double.parseDouble(String.copyValueOf(input, i, pointer-i));

return
reval;

}

//
返回下个不是num的

private int
getNextNotNum(int i) {

for (int
pointer = i + 1; pointer < input.length; pointer++) {

switch
(input[pointer]) {

case
'+':

case
'-':

case
'*':

case
'/':

case
'(':

case
')':

case
'=':

return
pointer;

}

}

return
-1;

}

//
返回左括号对应的右括号的位置

private int
getNextPL(int i) {

int count =
1;

for (int
pointer = i + 1; pointer < input.length; pointer++) {

switch
(input[pointer]) {

case
'(':

count++;

break;

case
')':

count--;

if(count ==
0){

return
pointer;

}

break;

}

}

return
-1;

}

class Node
{

double
val;

String
type;

public
Node(String type) {

this.type =
type;

}

public
Node(double val, String type) {

this.val =
val;

this.type =
type;

}

}

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