广交天下ACM爱好者
haha
hdu3596(逆波兰表达式求值)
/*************************************/
/*支持数字(而非表达式)前面有正负号 */
/*支持浮点数的+,-,*,/,^ 运算 */
/*************************************/
#include <stdio.h>
#include <memory>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <cmath>
#include <set>
#include <queue>
#include <time.h>
#include <limits>
#include <stack>
using namespace std;
#define N 10005
#define eps 1e-9
#define vType double
struct node{
vType val;
char op;
node(vType _val=0, char _op = ' '):val(_val), op(_op){}
}nodes[N];
char str[N];
inline bool isDigit(char ch){
return ch >= '0' && ch <= '9';
}
map<char, int> ms;
void init(){
ms['('] = 0;
ms['-'] = ms['+'] = 1;
ms['*'] = ms['/'] = 2;
ms['^'] = 3;
}
vType calPoland(node* nodes, int k){
int i, j;
vType a, b;
stack<vType> s;
for(i = 0; i < k; i++){
if(nodes[i].op == ' '){
s.push(nodes[i].val);
}else{
a = s.top();
s.pop();
b = s.top();
s.pop();
switch(nodes[i].op){
case '+':
s.push(b + a);
break;
case '-':
s.push(b - a);
break;
case '*':
s.push(b * a);
break;
case '/':
if(fabs(a) < eps) throw true;
s.push(b / a);
break;
case '^':
s.push(pow(b, a));
break;
}
}
}
return s.top();
}
vType poland(char* str){
int i, k, sign;
bool inNum, hasDot; //inNum标记当前是否可以输入数字, hasDot标记是否已经输入小数点
stack<char> oper;
for(i = k = 0, sign = 1, inNum = true; str[i]; i++){
if(isDigit(str[i]) || str[i] == '.'){
if(inNum){
vType val;
double w = 1;
if(str[i] == '.'){
hasDot = true;
val = 0;
}
else{
val = str[i] - '0';
hasDot = false;
}
i++;
while(isDigit(str[i]) || str[i] == '.'){
if(str[i] == '.'){
if(hasDot) throw true;
hasDot = true;
}else{
if(hasDot){
w *= 0.1;
val += (str[i] - '0') * w;
}
else val = val * 10 + str[i] - '0';
}
i++;
}
i--;
nodes[k++] = node(val * sign, ' ');
sign = 1;
inNum = false;
}else throw true;
}else{
switch(str[i]){
case '(':
oper.push(str[i]);
break;
case ')':
while(!oper.empty() && oper.top() != '('){
nodes[k++] = node(0, oper.top());
oper.pop();
}
if(oper.empty()) throw true; //没有与')'匹配的'('
oper.pop();
break;
case '+':
case '-':
case '*':
case '/':
case '^':
if(inNum){
if(str[i] != '+' && str[i] != '-') throw true;
while(str[i] == '+' || str[i] == '-'){
if(str[i] == '-') sign *= -1;
i++;
}
i--;
}else{
//while(!oper.empty() && ((str[i] != '^' && ms[str[i]] <= ms[oper.top()]) ||
// ((str[i] == '^' && ms[str[i]] < ms[oper.top()])))){ //如果^是右结合的话就用这个
while(!oper.empty() && ms[str[i]] <= ms[oper.top()]){
nodes[k++] = node(0, oper.top());
oper.pop();
}
oper.push(str[i]);
inNum = true;
}
break;
}
}
}
while(!oper.empty()){
nodes[k++] = node(0, oper.top());
oper.pop();
}
return calPoland(nodes, k);
}
void Cal(char* str){
try{
vType ans = poland(str);
printf("%.8lf\n", ans);
}
catch(bool){
printf("The teacher is so lazy!\n");
}
}
int main(){
#ifndef ONLINE_JUDGE
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif
init();
while(~scanf("%s", str)) Cal(str);
return 0;
}
posted on 2011-01-16 19:58
tw
阅读(697)
评论(0)
编辑
收藏
引用
所属分类:
HDU题解
只有注册用户
登录
后才能发表评论。
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
相关文章:
hdu3440(差分约束)
hdu3436(数据结构)
hdu3433(dp)
hdu3434
hdu3596(逆波兰表达式求值)
hdu 3624 (算术表达式求值)
网站导航:
博客园
IT新闻
BlogJava
知识库
博问
管理
Powered by:
C++博客
Copyright © tw
<
2024年11月
>
日
一
二
三
四
五
六
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
导航
C++博客
首页
新随笔
联系
聚合
管理
统计
随笔 - 0
文章 - 11
评论 - 0
引用 - 0
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
给我留言
查看公开留言
查看私人留言
文章分类
Game Problem(1)
(rss)
HDU题解(6)
(rss)
Math Theory(1)
(rss)
Timus题解(3)
(rss)
文章档案
2011年1月 (11)
搜索
最新评论