输入时字符串格式,例如1+2*3+(4+5)*6然后输出结果,支持括号。但是没有异常处理,字符串中不能有异常字符和空格。可能会有些bug,轻点喷。。。
#include <iostream>
#include <stack>
#include <stdlib.h>
using namespace std;
double ComputeStr(char *opStr);
double DealBrackets(char *str,int *incStep);
void DealOpCode(char *str,stack<double> *dsOperNum,stack<char> *csOperCode);
int main()
{
char opStr[20];
cin>>opStr;
cout<<"the oper string is "<<opStr<<endl;
double result = ComputeStr(opStr);
cout<<result<<endl;
}
double ComputeNum(double rnum,double lnum,char op)
{
double result=0.0;
switch(op)
{
case '+':
result = lnum + rnum;
break;
case '-':
result = lnum - rnum;
break;
case '*':
result = lnum * rnum;
break;
case '/':
result = lnum / rnum;
break;
default:
break;
}
return result;
}
double ComputeStr(char *opStr)
{
stack<double> dsOperNum;
stack<char> csOperCode;
dsOperNum.push(0.0);
csOperCode.push('+');
char *strIter=opStr;
double readnum = 0;
while(NULL != *strIter)
{
int incStep = 1;
if(*strIter>='0'&&*strIter<='9')
{
readnum = readnum*10 + (*strIter - '0');
}
else if('(' == *strIter)
{
readnum = DealBrackets(strIter,&incStep);//不用push readnum,后边会跟着操作符,然后进入下一个循环会push
}
else if(('+' == *strIter) ||
('-' == *strIter) ||
('*' == *strIter) ||
('/' == *strIter) )
{
dsOperNum.push(readnum);
DealOpCode(strIter,&dsOperNum, &csOperCode);
readnum=0;
}
strIter += incStep;
}
dsOperNum.push(readnum);
while(!csOperCode.empty())
{
double rnum=dsOperNum.top();
dsOperNum.pop();
double lnum=dsOperNum.top();
dsOperNum.pop();
double result = ComputeNum(rnum,lnum,csOperCode.top());
csOperCode.pop();
dsOperNum.push(result);
}
return dsOperNum.top();
}
double DealBrackets(char *str,int *incStep)
{
str++;//str是从(开始的
char *astIter = str;
while((')' != *astIter) && ('\0' !=astIter))
{
(*incStep)++;
astIter++;
}
char *astStoreBr = new char[(*incStep)];//incStep初始就为1
astIter = str;
memcpy(astStoreBr,astIter,(*incStep)-1);
astStoreBr[(*incStep)-1] = '\0';
double result = ComputeStr(astStoreBr);
free(astStoreBr);
return result;
}
bool CurOpIsPrior(char curCode,char oldCode)
{
if((('*'==curCode)||('/' == curCode))&&(('+' == oldCode)||('-' == oldCode)))
{
return true;
}
else
{
return false;
}
}
void DealOpCode(char *str,stack<double> *dsOperNum,stack<char> *csOperCode)
{
if(NULL == *str)
return;
if(CurOpIsPrior(*str,csOperCode->top()))
{
csOperCode->push(*str);
}
else
{
double rnum=dsOperNum->top();
dsOperNum->pop();
double lnum=dsOperNum->top();
dsOperNum->pop();
double result = ComputeNum(rnum,lnum,csOperCode->top());
csOperCode->pop();
dsOperNum->push(result);
csOperCode->push(*str);
}
}