formula.cpp
上传用户:hyb6888
上传日期:2016-01-24
资源大小:5186k
文件大小:7k
- #include "stdafx.h"
- #include "windows.h"
- #include "math.h"
- #include "formula.h"
- stackOP::stackOP()
- {
- topOP=-1;
- topNum=-1;
- }
- stackOP::~stackOP()
- {
- }
- ///////////////////////////////////////////////////////
- //数据栈
- bool stackOP::IsNullNum()
- {
- if(topNum>=0)
- return false;
- else
- return true;
- }
- double stackOP::pushNum(double num)
- {
- topNum++;
- return stackNum[topNum]=num;
- }
- double stackOP::pushNum(char *ss)
- {
- double total1=0,total2=0,tem=1,t;
- int point=-1,len,i;
- len=strlen(ss);
- for(i=0;i<len;i++)
- {
- if(ss[i]=='.')
- point=1;
- else
- {
- if('0'<= ss[i] && ss[i] <='9')
- {
- if(point==-1)
- total1=total1*10+(ss[i]-0x30);
- else
- {
- for(tem=1,t=0;t<point;t++)
- tem=tem*10;
- total2=total2+(ss[i]-0x30)/tem;
- point++;
- }
- }
- }
-
- }
- topNum++;
- return stackNum[topNum]=total1+total2;
- }
- int stackOP::popNum(double *Num)
- {
- int ret;
- if(topNum>=0)
- {
- *Num=stackNum[topNum];
- stackNum[topNum]=0;
- topNum--;
- ret = 0;
- }
- else
- {
- //MessageBox(0,"popNum","栈空",0);
- ret = -1;
- }
- return ret;
- }
- int stackOP::GetTopNum(double *lnum)
- {
- int ret;
- if(topNum>=0)
- {
- *lnum=stackNum[topNum];
- ret = 0;
- }
- else
- {
- //MessageBox(0,"栈空","栈空",0);
- ret = -1;
- }
- return ret;
- }
- /////////////////////////////////////////////////////////
- // 操作符栈
- // 进栈时并检查栈顶操作符,如果栈顶操作符大于本操作符,说明需要计算栈顶数据
- // 如果计算后还是大小本操作符就必须继续计算直到小于为止.
- //
- int stackOP::pushOP(char *ss)
- {
- int ret,flag=0;
- char lanOP[100]="";
- //空操作符最小,作为结束
- while(1)
- {
- ret=MycmpOP(ss);//操作符比较,返回为空说明栈已空
- if(ret>0) //本操作符大于栈顶操作符
- {
- if(ss[0]!=0&&ss[0]!=')') //如遇到空操作符就不再进栈.
- {
- topOP++;
- strcpy(stack[topOP],ss);
- }
- break;
- }
- else //等于或小于
- {
- if(flag=caculateOP()) //非0表示不再比较后序操作符
- {
- break;
- }
- }
- }
- //return -1 have false;
- return flag;
- }
- int stackOP::GetTop(char *ss)
- {
- int ret;
- if(topOP>=0)
- {
- strcpy(ss,stack[topOP]);
- ret = 0;
- }
- else
- {
- //MessageBox(0,"栈空","栈空",0);
- ret = -1;
- }
- return ret;
- }
- int stackOP::GetSort(char *ss)
- {
- char lanOP[100]="";
- int ret=-1;
- strcpy(lanOP,ss);
- if(strcmp(lanOP,"")==0)
- {
- ret=1;
- }
- if(strcmp(lanOP,"+")==0||strcmp(lanOP,"-")==0)
- {
- ret=10;
- }
- if(strcmp(lanOP,"*")==0||strcmp(lanOP,"/")==0)
- {
- ret=20;
- }
- if(strcmp(lanOP,"^")==0)
- {
- ret=30;
- }
- if(strcmp(lanOP,"~")==0)
- {
- ret=30;
- }
- if(strcmp(lanOP,")")==0)
- {
- ret=1;
- }
- if(strcmp(lanOP,"(")==0)
- {
- ret=-40;
- }
- return ret;
- }
- //操作符比较,返回为空说明栈已空
- int stackOP::MycmpOP(char *ss)
- {
- int ret;
- if(topOP<0)
- ret=1;
- else
- {
- //为正说明当前的操作符的优先级低于栈顶
- ret=abs(GetSort(ss))-GetSort(stack[topOP]);
- //当右括号与左括号比较左括号优先
- if(stack[topOP][0]=='(' , ss[0]==')')
- ret=-1;
- }
- return ret;
- }
- //非零说明有错误发生
- int stackOP::popOP(char *ss)
- {
- int ret;
- if(topOP<0)
- {
- MessageBox(0,"popOP","0",0);
- ret=-1;
- }
- else
- {
- strcpy(ss,stack[topOP]);
- stack[topOP][0]=0;
- topOP--;
- ret=0;
- }
- return ret;
- }
- //返回非0表示不再比较后序操作符
- //返回-1表示有错误发生
- //计算的结果依然存储在栈中
- int stackOP::caculateOP()
- {
- double num1,num2,num3,num4,num5;
- char lanOP[100]="";
- int ret=0,i;
- num1=num2=num3=num4=num5=0;
- if(popOP(lanOP))
- ret=-1;
- if(strcmp(lanOP,"^")==0)
- {
- if(popNum(&num2) || popNum(&num1))
- {
- ret=-1;
- //MessageBox(0,"popNum","栈空",0);
- }
- num3=1;
- for(i=1;i<=num2;i++)
- num3=num1*num3;
- pushNum(num3);
- }
- if(strcmp(lanOP,"+")==0)
- {
- if(popNum(&num2) || popNum(&num1))
- {
- ret=-1;
- //MessageBox(0,"popNum","栈空",0);
- }
- num2=num1+num2;
- pushNum(num2);
- }
- if(strcmp(lanOP,"-")==0)
- {
- if(popNum(&num2) || popNum(&num1))
- {
- ret=-1;
- //MessageBox(0,"popNum","栈空",0);
- }
- num2=num1-num2;
- pushNum(num2);
- }
- if(strcmp(lanOP,"*")==0)
- {
- if(popNum(&num2) || popNum(&num1))
- {
- ret=-1;
- //MessageBox(0,"popNum","栈空",0);
- }
- num2=num1*num2;
- pushNum(num2);
- }
- if(strcmp(lanOP,"/")==0)
- {
- if(popNum(&num2) || popNum(&num1))
- {
- ret=-1;
- //MessageBox(0,"popNum","栈空",0);
- }
- num2=num1/num2;
- pushNum(num2);
- }
- //右括号符相当于空操作符
- if(strcmp(lanOP,"(")==0)
- {
- ret =1;
- }
- return ret;
- }
- //返回为0说明正确
- int stackOP::GetResult(double *Num)
- {
- int ret=1;
- if( topOP==-1 && topNum==0)
- {
- *Num=stackNum[0];
- ret=0;
- }
- return ret;
- }
- ///////////////////////////////////////////////////////////
- formula::formula()
- {
- myflage=0;
- Exp=0;
- pExpscan=Exp;
- resultvar=0;
- }
- formula::~formula()
- {
- if(Exp!=0)
- delete []Exp;
- }
- /////////////////////////////////////
- // retss,收集到字符串
- //返回值:
- //-1,说明出现了错误
- //1,说明为数值
- //2,说明为操作符
- int formula::GetStr(char *retss)
- {
- int i,t=0,len,ret=-1;
- char *temss,*pp;
- pp=pExpscan;
- len=strlen(pp);
- temss=new char[len+1];
- temss[0]=0;
- t=0;
- for(i=0;i<=len;i++)
- {
- if(pp[i]=='.'||('0'<=pp[i] && pp[i]<='9'))
- {
- temss[t]=pp[i];
- t++;
- }
- else
- {
- temss[t]=0;
- if(temss[0]!=0) //说明有数字收集到temss中
- ret=1;
- else
- if(pp[i]!=0) //说明未到字符串尾部
- {
- temss[0]=pp[i];
- temss[1]=0;
- ret=2;
- }
- // t=0;
- // temss[0]=0;
- break;//得到一个串就结束。
- }
- }
- strcpy(retss,temss);
- // MessageBox(0,retss,temss,0);
- pExpscan+=strlen(temss);
- delete []temss;
- return ret;
- }
- //-1表示有错误发生
- formula::caculate(char *Expression)
- {
- char ss[100]=" ";
- int ret;
- myflage=0;
- setformula(Expression);
- while((ret=GetStr(ss))!=-1)
- {
- if(1==ret)
- {
- stackop.pushNum(ss);
- }
- if(2==ret)
- {
- myflage=stackop.pushOP(ss);
- if(myflage==-1)
- break; //表示有错误发生
- }
- }
- if(myflage!=-1)
- {
- myflage=stackop.pushOP("");
- stackop.GetResult(&resultvar);
- }
- }
- int formula::getformulaVar(double *Num)
- {
- stackop.GetResult(Num);
- return myflage;
- }
- //设置公式的表达式字符串
- formula::setformula(char *Expression)
- {
- int i,t=0,len;
- //去掉多余的空格
- len=strlen(Expression);
- if(Exp!=0)
- delete []Exp;
-
- Exp=new char[len+1];
- for(i=0;i<len;i++)
- {
- if(Expression[i]!=' ')
- {
- if(Expression[i]==-93 && Expression[i+1]==-85)
- {
- Exp[t]='+';
- i++;
- t++;
- continue;
- }
- if(Expression[i]==-93 && Expression[i+1]==-83)
- {
- Exp[t]='-';
- i++;
- t++;
- continue;
- }
- if( Expression[i]==-95&&Expression[i+1]==-63)
- {
- Exp[t]='*';
- t++;
- i++;
- continue;
- }
- if( Expression[i]==-95&&Expression[i+1]==-62)
- {
- Exp[t]='/';
- i++;
- t++;
- continue;
- }
- Exp[t]=Expression[i];
- t++;
- }
- }
- Exp[t]=0;
- //MessageBox(0,Exp," d",0);
- pExpscan=Exp;
- }