例如:直接输入2+12*(5-1+(4/3))*2
例如:直接输入2+12*(5-1+(4/3))*2
#include<iostream>
#include<cstdlib>
#include<cctype>
//函数原型
int addsubt();
int multdiv();
int number();
void error();
//全局表达式缓冲器
static char expr[100];
static int pos;
/////////////////////////
//main函数
////////////////////////
int main()
{
int ans;
do
{
//初始化字符串下标
pos=0;
//读取表达式
std::cout<<"Enter expression (0 to quit):"<<endl:
std::cin>>expr;
//表达式求值
ans=addsubt();
if(expr[pos]!='\0')
error();
if(ans!=0)
std::cout<<ans<<endl;
}
while(ans!=0);
return 0;
}
///////////////////////
//逆序递归的顶层:加/减
///////////////////////
int addsubt()
{
int rtn = multdiv();
while(expr[pos]=='+'||expr[pos]=='-')
{
int op = expr[pos++];
int opr2=multdiv();
if(op=='+') rtn+=opr2;
else rtn-=opr2;
}
return rtn;
}
///////////////////////
//最高优先级:乘/除
///////////////////////
int multdiv()
{
int rtn = number();
while(expr[pos]=='*'||expr[pos]=='/')
{
int op = expr[pos++];
int opr2=number();
if(op=='*') rtn*=opr2;
else rtn/=opr2;
}
return rtn;
}
///////////////////////
//开括号
///////////////////////
int number()
{
int rtn;
if(expr[pos]=='(')
{
pos++;
rtn=addsubt(); //返回顶层
if(expr[pos]!=')') //必须有‘)’
error();
return rtn;
}
if(!isdigit(expr[pos]))
error();
rtn=atoi(expr+pos);
while(isdigit(expr[pos]))
pos++;
return rtn;
}
///////////////////////
//语法错误
///////////////////////
void error()
{
etd::cout<<'\r';
while(pos--)
std::cout<<' ';
std::cout<<"^syntax error"<< std::endl <<'\a';
exit(-1);
}
我还想问一下,用指针遍历字符数组,应该怎么做啊?比如:将输入的字符串逐个压入栈A,直到扫到第一个‘)’,然后开始从栈A弹出,并把弹出的数压入另外一个栈B中(这个栈内的数字都是无括号的),直到弹出‘(’时停止,计算栈B中的无括号表达式,并将结果存入栈A中,然后栈A的指针移到刚才弹出第一个右括号的位置,继续重复见面的行为,直到没有括号,就可以计算无括号的表达式了。
但是具体实现起来好相复杂很多,请问怎么搞?
我的方法是对所有运算符号都设置优先级,*/大于+-,括号内的大于括号外的
只要有第2个运算符号出现, 就比较这两个运算符号的优先级,如果第2个符号优先级大, 则第一个运算符号入栈, 继续等待第三个运算符号,如果第2个符号优先级小,则进行第一个运算符号的运算.
具体方法见如下帖
http://www.bc-cn.net/bbs/dispbbs.asp?boardID=179&ID=34970&page=1