C++实现数学表达式的计算Word文档下载推荐.docx
《C++实现数学表达式的计算Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《C++实现数学表达式的计算Word文档下载推荐.docx(20页珍藏版)》请在冰豆网上搜索。
#include"
stdafx.h"
math.h"
#include<
stack>
usingnamespacestd;
MathExpression.h"
//检查字符是否合法。
完成一些非标准符号的转换
//返回值:
true成功,false存在非法字符。
staticboolCheckChar(wchar_t&
wch)
switch(wch)
{
case__T('
('
):
wch='
;
//将中文的括号换成ASCII的括号
break;
)'
):
case'
E'
:
e'
//将浮点数的阶码符号E一律换成小写的e
'
x'
X'
*'
//将数学的×
(包括字母:
xX)改成标准的*
÷
/'
}
//检查字符的合法性
if(wch>
='
0'
&
&
wch<
9'
)//是数字
returntrue;
elseif(wch=='
'
||wch=='
.'
)
//合法的操作符
elseif(wch=='
+'
-'
^'
%'
\0'
//结束符,合法
//挑选剩余的是非法字符
returnfalse;
}
//去除空格,将中文的括号换成ASCII的括号,将浮点数的阶码符号E一律换成小写的e。
//将数学的×
xX)改成标准的*、÷
改成标准的/。
boolStringPreprocess(wchar_t*pwch)
inti=0,j=0;
//循环计数变量
wchar_ttmp;
intParenthesesCount=0;
//用于判断括号是否匹配
for(;
)//使用for循环效率较高
{//去除空格
tmp=pwch[j];
//使用临时变量,提高效率
if(!
CheckChar(tmp))returnfalse;
//检查字符是否合法。
if(tmp==0)
{//扫描完毕
pwch[i]=0;
//写入字符串结束的符号
break;
}
else
{
if(tmp=='
)//是空格,不予保留
j++;
//继续扫描下一个
else
{//不是空格,保留数据。
方式是前移
pwch[i]=tmp;
//计数'
、'
if(tmp=='
)ParenthesesCount++;
elseif(tmp=='
)ParenthesesCount--;
i++;
j++;
}
if(ParenthesesCount==0)
//括号匹配
else
returnfalse;
//括号不匹配
//提取数型数据。
staticdoublePickupValue(constwchar_t*pwch,int&
pos)
doublesign=1.0;
//用于记录符号
doubleesign=1.0;
//用于记录指数符号
wchar_tcurwch;
doublemantissa=0.0,mantissa_decimal=0.0;
doubleexponent=0.0,exponent_decimal=0.0;
doublex;
curwch=pwch[pos];
if(curwch=='
{//是符号-
sign=-1.0;
//记录下来
pos++;
//指向下一个字符
elseif(curwch=='
{//是符号+
sign=1.0;
//将表示尾数的字符串转换成数
)//运行效率比while
(1)高
{//计算尾数的整数部分
curwch=pwch[pos];
//取当前字符。
if(curwch<
||curwch>
)break;
//不是数字
mantissa=mantissa*10.0+(curwch-'
);
//计算尾数。
{//计算尾数的小数部分
x=1.0;
//用于累计乘以10的次数
for(;
{//计算尾数的小数部分
curwch=pwch[pos];
if(curwch<
mantissa_decimal=mantissa_decimal*10.0+(curwch-'
//计算尾数
x*=10.0;
pos++;
mantissa_decimal/=x;
mantissa+=mantissa_decimal;
//尾数=整数部分+小数部分
mantissa*=sign;
//将符号加上
{//接下来的是阶码
if(curwch=='
{//是符号-
esign=-1.0;
elseif(curwch=='
{//是符号+
esign=1.0;
{//将表示阶码的字符串转换成数
exponent=exponent*10.0+(curwch-'
//计算阶码
{//计算指数的小数部分
x=1.0;
for(;
{//计算尾数的小数部分
curwch=pwch[pos];
if(curwch<
exponent_decimal=exponent_decimal*10.0+(curwch-'
x*=10.0;
pos++;
exponent_decimal/=x;
exponent+=exponent_decimal;
//阶码=整数部分+小数部分
exponent*=esign;
returnmantissa*pow(10,exponent);
//返回结果:
浮点数数=尾数*10^阶码
//判断当前是否是操作数。
是:
返回1,不是:
返回0,非法表达式:
-1
staticintIsOperand(constwchar_t*pwch,intpos)
{
wchar_tcurwch=pwch[pos],tmpwch;
boolb1,b2;
if(curwch>
curwch<
)return1;
//是数字就不必说,肯定是操作数
||curwch=='
{//是+-
if(pos==0)
{//第一个字符
if(pwch[pos+1]>
pwch[pos+1]<
return1;
//紧接着的是数字,当前是操作数
//return-1;
{
if(pwch[pos+1]=='
)//是修饰括号内结果的符号
return0;
else//紧接着的不是数字也不是'
,表达式非法
return-1;
{//不是第一个字符
tmpwch=pwch[pos-1];
//使用临时变量,提高程序效率和可读性
//前面是‘)’或者是数字、或者是小数点
b1=(tmpwch>
tmpwch<
b1=(b1||tmpwch=='
tmpwch=pwch[pos+1];
b2=tmpwch>
//后面是数字。
if(!
b1&
b2)
return0;
{//以小数点开头的一般也是数
return-1;
//打头小数点后不是数字,肯定非法
return0;
//判断操作符的优先级
//#|(|一元-+|^|*/%|+-|)
//isp0|1|9|7|5|3|10
//icp0|10|8|6|4|2|1
staticvoidJdugePriority(ExpressionItem&
ei)
{//这里不判断#、一元-+的优先级
switch(ei.OperateChar)
ei.Isp=1;
ei.Icp=10;
ei.Isp=7;
ei.Icp=6;
ei.Isp=5;
ei.Icp=4;
ei.Isp=3;
ei.Icp=2;
ei.Isp=10;
ei.Icp=1;
default:
ei.Isp=0;
ei.Icp=0;
//判断符号是否是修饰括号内结果的符号
staticboolSignBrackets(constwchar_t*pwch,intpos)
wchar_ttmpwch;
if(pwch[pos]=='
||pwch[pos]=='
if(pwch[pos+1]=='
{//后如果是(
if(pos==0)returntrue;
//首个-+当然是数的符号
((tmpwch>
)||tmpwch=='
||tmpwch=='
))
returntrue;
//前面不是数字
//表达式有效性检测
staticboolExpressionValid(constExpressionItem*pEi,intcount)
{//有效的检测:
项数必为奇数,一定是一操作数开始,不计括号,操作数与操作符交替出现。
if(count<
3)returnfalse;
//表达式最少有3项
wchar_twch=pEi[0].OperateChar;
if(wch!
=0)returnfalse;
//表达式一定是一操作数开始
boolis_operand=true;
inti;
for(i=0;
i<
count;
i++)
{//表达式的操作数与操作符交替出现
wchar_twch=pEi[i].OperateChar;
if(wch=='
)continue;
//不计括号
if(is_operand)//当前应该是操作数。
操作数:
wch==0
if(wch!
else//当前应该是操作符。
操作符:
wch!
=0
if(wch==0)returnfalse;
is_operand=!
is_operand;
returntrue;
//通过重重检测,表达式有效
//解析表达式。
intAnalyzeExpression(constwchar_t*pwch,ExpressionItem*pOut)
intpos=0,k=0;
inta;
if(curwch==0)break;
//结束循环
//判断是操作数还是操作符
a=IsOperand(pwch,pos);
if(a==-1)return0;
//非法表达式
if(a==1)
{//是操作数
pOut[k].Operand=PickupValue(pwch,pos);
pOut[k].OperateChar=0;
pOut[k].Isp=0;
pOut[k].Icp=0;
k++;
//准备输出下一个解析结果
{//是操作符
if(SignBrackets(pwch,pos))
{//符号是修饰括号内结果的符号。
//插入一个操作数:
pOut[k].Operand=0;
pOut[k].OperateChar=0;
pOut[k].Isp=0;
pOut[k].Icp=0;
k++;
//输出这个特殊的高优先级的双目减(加)法
pOut[k].OperateChar=curwch;
pOut[k].Isp=9;
pOut[k].Icp=8;
//指向下一个字符
{//符号是修饰括号内结果的符号
pOut[k].Operand=0.0;
JdugePriority(pOut[k]);
//确定优先级
if(!
ExpressionValid(pOut,k))return0;
//表达式有效性检测:
无效
//在表达式最后放一个“#”
pOut[k].Operand=0.0;
pOut[k].OperateChar='
#'
pOut[k].Isp=0;
pOut[k].Icp=0;
returnk+1;
//转换结果通过pOut输出,pOut内存分配由调用者负责。
intInfixToPostfix(ExpressionItem*pIn,ExpressionItem*pOut,intExpressionItemsCount)
stack<
ExpressionItem>
s;
ExpressionItemch,op;
inti,j;
ch.Operand=0.0;
ch.OperateChar='
ch.Isp=0;
ch.Icp=0;
s.push(ch);
//栈底放一个‘#’
i=0;
ch=pIn[i];
//读入一个字符(取表达式第一个元素)
j=0;
while(!
s.empty()&
ExpressionItemsCount)
if(ch.OperateChar=='
intx=0;
if(i==22)
if(ch.OperateChar==0)
{//是操作数,则输出之
pOut[j]=ch;
j++;
//输出
i++;
if(i>
=ExpressionItemsCount)return0;
ch=pIn[i];
//读下一个字符(取表达式下一个元素)
if(ch.Icp>
s.top().Isp)
{//新输入(当前)的操作符优先级高
s.push(ch);
//进栈
if(i>
ch=pIn[i];
elseif(ch.Icp<
{//新输入(当前)的操作符优先级低
op=s.top();
//取栈顶元素
s.pop();
//退栈
pOut[j]=op;
{//输入的优先级等于栈定的优先级
if(op.OperateChar=='
{
i++;
if(i>
ch=pIn[i];
//读下一个字符(取表达