前言:一直像做个计算器,但是表达式求值算法不会写。昨天数据结构老师刚好讲到表达式求值就下决心将这个代码敲出来。之所以说这个是hdu 1237升级版是因为这个代码支持括号嵌套。
思路: 主要分两步。
- 将中缀表达式转换为后缀表达式.大家可以参考这个博客(侵删):
- 求解中缀表达式
- 我将每个数的第一位所在下标的book 数组标志为假
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stack>
using namespace std;
const int N = 2000;
typedef struct
{
char arr[N];
bool book[N];
int top;
}note;
note strk_int,strk_str;
inline void init(char *str); //将中缀表达式转化为后缀表达式
int main()
{
int sum,flag = 0;
char str[N];
while (gets(str))
{
if(strcmp(str,"0") == 0) break;
stack<double> strk;
init(str);
while (strk_str.top != 0)
strk_int.arr[++strk_int.top] = strk_str.arr[strk_str.top--];
// for(int i=1; i<=strk_int.top; i++)
// cout<<strk_int.arr[i]<<" ";
// cout<<endl;
// for(int i=1; i<=strk_int.top; i++)
// cout<<strk_int.book[i]<<" ";
// cout<<endl;
for(int i=1; i<strk_int.top; ) //对后缀表达式求值
{
sum = flag = 0;
while (strk_int.arr[i]>='0' && strk_int.arr[i]<='9')
{
if(flag == 1 &&strk_int.book[i] == 0) break;
flag = 1;
sum = sum*10 + strk_int.arr[i]-'0';
i++;
}
if(flag)
strk.push(sum);
else
i++;
if((strk_int.arr[i]<'0' || strk_int.arr[i]>'9'))
{
// cout<<"this is "<<strk_int.arr[i]<<endl;
double num1 = strk.top(); strk.pop();
double num2 = strk.top(); strk.pop();
double num3;
switch (strk_int.arr[i])
{
case '+':
num3 = num2 + num1;
break;
case '-':
num3 = num2 - num1;
break;
case '*':
num3 = num2 * num1;
break;
case '/':
num3 = num2 / num1;
default:
break;
}
strk.push(num3);
}
}
/*while (!strk.empty())
{
cout<<strk.top()<< " ";
strk.pop();
}*/
double ans = strk.top(); //strk.pop();
printf("%.02f\n",ans);
}
return 0;
}
inline void init(char *str)
{
bool is = false;
int len = strlen(str),flag = 0;
memset(&strk_int,0,sizeof(strk_int));
memset(&strk_str,0,sizeof(strk_str));
for(int i=0; i<len; i++)
{
if(str[i] == ' ')
{
is = false;
continue;
}
else if(str[i] >='0' && str[i]<='9')
{
strk_int.arr[++strk_int.top] = str[i];
if(is == true)
strk_int.book[strk_int.top] = 1; //每个数的第一位,其对应下标的book数组的值是false , 以此作为正确求出每个数的依据
is = true;
}
else
{
is = false;
if(str[i] == '(')
strk_str.arr[++strk_str.top] = '(' , flag++;
else if(str[i] == ')')
{
while (strk_str.arr[strk_str.top] != '(')
{
strk_int.arr[++strk_int.top] = strk_str.arr[strk_str.top--];
}
strk_str.top-- , flag--;
}
else
{
if(str[i]=='+' || str[i]=='-') //遇 +,- 将栈中元素清除
{
while (strk_str.top != 0 && strk_str.arr[strk_str.top]!='(')
strk_int.arr[++strk_int.top] = strk_str.arr[strk_str.top--];
strk_str.arr[++strk_str.top] = str[i];
}
// else if(strk_str.top>0 && (strk_str.arr[1] =='*' || strk_str.arr[1]=='/'))
// {
// while (strk_str.top != 0 && strk_str.arr[strk_str.top]!='(' )
// strk_int.arr[++strk_int.top] = strk_str.arr[strk_str.top--];
// strk_str.arr[++strk_str.top] = str[i];
// }
else // * / 将遇到+ , - ( , )之前的 * / 清除
{
while (strk_str.top!=0 && (strk_str.arr[strk_str.top]=='*' || strk_str.arr[strk_str.top]=='/'))
{
strk_int.arr[++strk_int.top] = strk_str.arr[strk_str.top--];
}
strk_str.arr[++strk_str.top] = str[i];
}
}
}
}
}