//
// main.cpp
// project4
//
// Created by 张 云东 on 14-4-15.
// Copyright (c) 2014年 张云东. All rights reserved.
//
#include <iostream>
#include <math.h>
using namespace std;
#define SIZE 100
#define CRE 10
#define TRUE 1
#define FALSE 0
#define Max1 1000001
#define Max2 1000002
#define X 10000003
template <typename Type>
class stack
{
public:
Type *base;
Type *top;
int stacksize;
stack()
{
base=(Type *)malloc(SIZE * sizeof(Type));
if (!base) exit(OVERFLOW);
top=base;
stacksize=SIZE;
}
Type GetTop()
{
if (base==top) return0;
return *(top-1);
}
Type Push(Type c)
{
if (top-base>=stacksize)
{
base=(Type *)realloc(base, (stacksize+CRE)*sizeof(Type));
if (!base) exit(OVERFLOW);
top=base+stacksize;
stacksize+=CRE;
}
*top=c;
*top++;
return 1;
}
Type Pop(Type &c)
{
if (top==base) return0;
c=*--top;
return 1;
}
};
char c;
float x1,x2;
bool flag;
float func(float a,char ch,float b)//计算表达式的微分值
{
switch(ch)
{
case '+':return(a+b);
case '-':return(a-b);
case '*':return(a*b);
case '^':
if ((fabs(a-0)<0.000001)&&(b<0))
{
cout<<"表达式有误,0的负次幂无法运算;"<<endl;
return 0;
}
else return powf(a, b);
case '%':
if (fabs(b-0)<0.000001)
{
cout<<"表达式有误,不能对0取模;"<<endl;
return 0;
}
else return fmodf(a, b);
case '/':
if(b==0)
{
cout<<"表达式有误,分母不能为0;"<<endl;
return 0;
}
else
return(a/b);
default :cout<<"输入有误;"<<endl;return 0;
}
};
float Operate(float a,char oper,float b)
{
if (flag==1&&(a==X||b==X))
{
int i,N=1000;
float dt=(x2-x1)/N;
float y=0.0;
float (*f)(float,char,float);
f=&func;
for (i=0;i<N;i++)
{
if (a==X&&b!=X)
y+=(*f)(x1+(float)i*dt,oper,b)*dt;
else if (a==X&&b==X)
y+=(*f)(x1+(float)i*dt,oper,x1+(float)i*dt)*dt;
else y+=(*f)(a,oper,x1+(float)i*dt)*dt;
}
return y;
}
else
switch(oper)
{
case '+':return(a+b);
case '-':return(a-b);
case '*':return(a*b);
case '^':
if ((fabs(a-0)<0.000001)&&(b<0))
{
cout<<"表达式有误,0的负次幂无法运算;"<<endl;
return 0;
}
else return powf(a, b);
case '%':
if (fabs(b-0)<0.000001)
{
cout<<"表达式有误,不能对0取模;"<<endl;
return 0;
}
else return fmodf(a, b);
case '/':
if(b==0)
{
cout<<"表达式有误,分母不能为0;"<<endl;
return 0;
}
else
return(a/b);
default :cout<<"输入有误;"<<endl;return 0;
}
}
int In(char ch)
{
if(ch>='0'&&ch<='9'||ch=='.')
return1;
else
return0;
}
char compare(char a,char b )
{
int i=0,j=0;
char array[9][9] = {
{'>','>','<','<','<','>','>','<','<'},
{'>','>','<','<','<','>','>','<','<'},
{'>','>','>','>','<','>','>','<','>'},
{'>','>','>','>','<','>','>','<','>'},
{'<','<','<','<','<','=',' ','<','<'},
{'>','>','>','>',' ','>','>','>','>'},
{'<','<','<','<','<',' ','=','<','<'},
{'>','>','>','>','<','>','>','>','>'},
{'>','>','>','>','<','>','>','<','>'}};
switch(a)
{
case '+':i=0;break;
case '-':i=1;break;
case '*':i=2;break;
case '/':i=3;break;
case '(':i=4;break;
case ')':i=5;break;
case '#':i=6;break;
case '^':i=7;break;
case '%':i=8;break;
}
switch(b)
{
case '+':j=0;break;
case '-':j=1;break;
case '*':j=2;break;
case '/':j=3;break;
case '(':j=4;break;
case ')':j=5;break;
case '#':j=6;break;
case '^':j=7;break;
case '%':j=8;break;
default: return0;
}
return array[i][j];
}
float Evaluate()
{
cout<<"开始时:"<<endl;
cout<<"输入1进入积分运算模式,输入0进入多项式运算模式"<<endl;
c=getchar();
if (c=='1')
{
flag=1;
cin>>x1>>x2;
}else flag=0;
c=getchar();
stack<char> ope;
stack<float> data;
int mark1=0,mark2=0,mark3=0,n=1;
char oper,y;
float a,b,x,w;
ope.Push('#');
cout<<"请输入表达式(以'#'结束):"<<endl;
c=getchar();
while(c!='#'||ope.GetTop()!='#')
{
if(In(c))
{
mark2=0; //不止一位时用mark2来记录
if(mark1==1)
{
if(c=='.'||mark3)
{
if(mark3) //当是小数,mark3来标记小数的个数
{
n*=10;
data.Pop(x);
w=x+(c-48)/float(n);
data.Push(w);
}
if(c=='.'&&mark3)
return Max2;
mark3++;
}
else
{
data.Pop(x);
data.Push(x*10+(c-48));
}
}
else data.Push(c-48);
mark1=1;
c=getchar();
}
else if (c=='x') {data.Push(X);c=getchar();mark2=0;}
else
{
if (!data.GetTop()&&c=='-') {data.Push(0);}
mark1=0;
mark3=0;
n=1;
if(mark2==1&&ope.GetTop()!=')'&&c!='(')
{
if (c!='+'&&c!='-')//连续两个运算符
{
return Max2;
}
else
{
data.Push(0);
}
}
mark2=1;
switch(compare(ope.GetTop(),c))
{
case'<':
ope.Push(c);
c=getchar();
break;
case'=':
ope.Pop(y);
mark2=0;
c=getchar();
break;
case'>':
ope.Pop(oper);
data.Pop(b);
data.Pop(a);
data.Push(Operate(a, oper, b));
mark2=0;
break;
case0:
return Max1;
}
}
}
return data.GetTop();
}
int main()
{
char ch;
float result;
cout<<"********************************************************************************";
cout<<"*********************************算术表达式求值*********************************";
do
{
result=Evaluate();
if(result==Max1)
{
cout<<"表达式中有无法识别的字符!!!"<<endl<<endl<<endl<<endl;
}
else if(result==Max2)
{
cout<<"表达式中操作符不匹配!!!"<<endl<<endl<<endl<<endl;
}
else
{
cout<<"result=";
cout<<result<<endl<<endl;
}
cin.ignore(100,'\n');
cout<<"是否要继续(Y or N):";
cin>>ch;
cin.ignore();
}while(ch=='Y');
return 0;
}