您的位置:首页 > 其它

郁闷的C小加(三)(nyoj 409)

2014-03-15 14:26 274 查看


郁闷的C小加(三)

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

描述聪明的你帮助C小加解决了中缀表达式到后缀表达式的转换(详情请参考“郁闷的C小加(一)”),C小加很高兴。但C小加是个爱思考的人,他又想通过这种方法计算一个表达式的值。即先把表达式转换为前缀和后缀表达式,再求值。这时又要考虑操作数是小数和多位数的情况。

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

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

数据保证除数不会为0。
输出对于每组测试数据输出结果包括三行,先输出转换后的前缀和后缀表达式,再输出计算结果,结果保留两位小数。
样例输入
2
1+2=
(19+21)*3-4/5=


样例输出
+ 1 2 =
1 2 + =
3.00
- * + 19 21 3 / 4 5 =
19 21 + 3 * 4 5 / - =
119.20


中缀转前缀:

从后往前

得到一个操作符或者操作数。

如果是操作数就输入到数组,

如果是')'压栈,

如果是'(' 栈顶出栈直到栈顶为')',然后将')'也弹出

如果是运算符,优先级大于等于栈顶元素,压栈

优先级小于栈顶元素,反复出栈,并将出栈的元素输入到数组,直到优先级大于等于栈顶元素,并将此运算符压栈

输入结束,就将栈里的元素全部出栈输入到数组,直到栈空。

中缀转后缀:

从前往后

得到一个操作符或者操作数。

如果是操作数就输入到数组,

如果是'('压栈,

如果是')' 栈顶出栈直到栈顶为'(',然后将'('也弹出

如果是运算符,优先级大于栈顶元素,压栈

优先级小于等于栈顶元素,反复出栈,并将出栈的元素输入到数组,直到优先级大于栈顶元素,并将此运算符压栈

输入结束,就将栈里的元素全部出栈输入到数组,直到栈空。

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <stack>
using namespace std;

char a[1010], b[1010], c[1010];//b后缀,c前缀
int k = 0;
stack<char> s;
stack<double> num;

int first(char ch)
{//优先级
switch(ch)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
default:
return 0;
}
}

void change1()
{//中缀转前缀
int i, len = strlen(a);
char t;
s.push('#');
c[k ++] = '=';
for(i = len - 2; i>= 0;)
{
if(isdigit(a[i]) || a[i] == '.')
{
c[k ++] = ' ';
while(isdigit(a[i]) || a[i] == '.')
{
c[k ++] = a[i];
i --;
}
}
else if(a[i] == ')')
{
s.push(a[i]);
i --;
}
else if(a[i] == '(')
{
t = s.top();
while(t != ')')
{
c[k ++] = ' ';
c[k ++] = t;
s.pop();
t = s.top();
}
s.pop();
i --;
}
else
{
t = s.top();
while(first(a[i]) < first(t))
{
c[k ++] = ' ';
c[k ++] = t;
s.pop();
t = s.top();
}
s.push(a[i]);
i --;
}
}
t = s.top();
while(t != '#')
{
c[k ++] = ' ';
c[k ++] = t;
s.pop();
t = s.top();
}
c[k ++] = '\0';
}

void change2()
{//中缀转换为后缀
int len = strlen(a);
int i;
s.push('#');
for(i = 0; i < len - 1;)
{
if(isdigit(a[i]) || a[i] == '.')
{
while(isdigit(a[i]) || a[i] == '.')
{
b[k ++] = a[i];
i++;
}
b[k ++] = ' ';
}
else if(a[i] == '(')
{
s.push(a[i]);
i++;
}
else if(a[i] == ')')
{
while(s.top() != '(')
{
b[k ++] = s.top();
s.pop();
b[k ++] = ' ';
}
s.pop();
i++;
}
else
{
char t = s.top();
while(first(t) >= first(a[i]))
{
b[k ++] = t;
b[k ++] = ' ';
s.pop();
t = s.top();
}
s.push(a[i]);
i++;
}
}
char t = s.top();
while(t != '#')
{
b[k ++] = t;
s.pop();
b[k ++] = ' ';
t = s.top();
}
b[k ++] = '=';
b[k ++] = '\0';
}

void g(char x)
{//计算
double a = num.top();
num.pop();
double b = num.top();
num.pop();
switch(x)
{
case'+':
num.push(a + b);
break;
case'-':
num.push(b - a);
break;
case'*':
num.push(a * b);
break;
case'/':
num.push(b / a);
break;
}
}

void count()
{//根据后缀式计算
int i, len = strlen(b);
double temp = 0;
for(i = 0; i < len - 1; )
{
if(isdigit(b[i]) || b[i] == '.')
{
int f = 0;
while(isdigit(b[i]) || b[i] == '.')
{
if(isdigit(b[i]))
{
temp = temp * 10 + (b[i] - '0');
if(f != 0)
f ++;
}
else
f = 1;
i++;
}
if(f != 0)
temp = temp / pow(10, f - 1);
//printf("%lf\n", temp);
num.push(temp);
temp = 0;
}
else if(b[i] == ' ')
{
i++;
}
else
{
g(b[i]);
i++;
}
}
}

int main (void)
{
int n, i;
scanf("%d", &n);
while(n --)
{
scanf("%s", a);
change1();
k = 0;
change2();
count();
for(i = strlen(c) - 1; i >= 0; i--)
{
printf("%c", c[i]);
}
printf("\n");
printf("%s\n", b);
printf("%.2lf\n", num.top());
num.pop();
k = 0;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: