前言:一直像做個計算器,但是表達式求值算法不會寫。昨天數據結構老師剛好講到表達式求值就下決心將這個代碼敲出來。之所以說這個是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];
}
}
}
}
}