此题可以使数据结构课中的栈来实现,也可以用表达式树来实现,追根溯源两种方法都是用栈实现的。
此处仅讲表达式树的做法,(对1312这题来说,运算符有三级,最高级^,次级*/,最低级+-)一个表达式,如2*3/(2-1)+5*(4-1),表达式树会找到+,并以此位根节点建立左右支树,以此类推,表达式树的建立如下图:
回溯的时候,便会返回+号左右的值想加,右边又会返回/号左右的值相除,右边会返回*左右的值相乘。这样一来得到结果为21.00。
参考代码如下:
#include<stdio.h>
double calc(char* s,long len)
{
long i,k=0,mid=-1,md=0,lent=0;
double sm=0,d=10;
for(i=0;i<len;i++)
switch(*(s+i))
{
case '+': case '-':
if(!k) mid=i; break;
case '*': case '/':
if(!k&&mid==-1) mid=i; break;
case '^':
if(!k&&mid==-1&&!md) mid=i; break;
case '(': k++; break;
case ')': k--; break;
case '.': d=1; lent++; break;
default: if(d!=10){ d*=0.1; sm+=(*(s+i)-'0')*d; }
else sm=sm*d+*(s+i)-'0'; lent++; break;
}
if(mid==-1&&lent!=len) return calc(s+1,len-2);
if(lent==len) return sm;
else
{
switch(*(s+mid))
{
case '+': return calc(s,mid)+calc(s+mid+1,len-mid-1); break;
case '-': return calc(s,mid)-calc(s+mid+1,len-mid-1); break;
case '*': return calc(s,mid)*calc(s+mid+1,len-mid-1); break;
case '/': return calc(s,mid)/calc(s+mid+1,len-mid-1); break;
case '^': return pow(calc(s,mid),calc(s+mid+1,len-mid-1)); break;
}
}
}
int main()
{
char s[1001];
scanf("%s",s);
printf("%.2lf\n",calc(s,strlen(s)-1));
return 0;
}