算法核心:
一般表达式都采用的中缀表达式,而中缀表达式不仅要依赖运算符优先级,还要处理括号。所以,对于中缀表达式,一般是先将其化作后缀表达式,在后缀表达式中只有操作符和运算符,而且越放在前面的运算符越先执行。
算法步骤:
1.将算术表达式转换为后缀表达式。先设置两个数组,一个是用于存放后缀表达式的res[]数组,另一个是用于当作栈使用用于存放运算符的Stack[]数组,每取一个字符:
(1)当遇到运算符时:
a.若该运算符的优先级比目前Stack[]栈顶的运算符高时,直接入栈;
b.若运算符的优先级没有Stack[]栈顶的运算符高时,则不断出栈,直到该运算符优先级比目前Stack[]栈顶的运算符高为止,对于出栈的字符都存于res[]数组。
(2)当遇到括号字符时:
a.若为左括号,则直接入栈;
b.若为右括号,则不断出栈,并将出栈的符号存于res[]中,直到出栈符号为左括号。
(3)当遇到数字字符时,则直接存于res[]数组。
最后,将栈中的所有字符依次出栈到res[]数组中去。
2.对得到的后缀表达式求值。依次从res[]的左到右处理字符串,每取一个字符:
(1)当字符为数字字符时,则进行入栈保存;
(2)当字符为运算符时,则进行出栈两次的操作,将出栈得到的两个数字进行相应的运算,并将结果进行入栈。
直到所有字符取完为止。
注意:(1)在res[]数组中,为了防止两个数字混淆在一起,会在两个数字中间加一个‘#’,如何保证每两个数之间都有‘#’呢?可以利用每两个数字之间一定有运算符的特点,每遇到一个运算符,就先在res[]中存一个‘#’;
(2)在对运算符设置优先级时要仔细,‘(’的优先级应该是最低的。
实例以及代码
char Stack[100]; //当作一个栈使用,存储运算符
int top=-1,k;
int rank[100];
//对运算符优先级进行量化
void InitialRank(){
rank['(']=0;
rank['+']=1;
rank['-']=1;
rank['*']=2;
rank['/']=2;
}
//出栈入栈运算符
void Push(char a){
top++;
Stack[top]=a;
}
char Pop(){
char ch;
ch=Stack[top];
top--;
return ch;
}
//接收输入数据
int Input(char c[]){
int i=0;
char ch;
printf("简易计算器\n");
printf("请输入表达式:");
ch=getchar();
while(ch!='\n')
{
c[i++]=ch;
ch=getchar();
}
return i;
}
//转换为后缀表达式
void PostExpression(char c[],int n,char res[]){
int i;
char ch;
for(i=0;i<n;i++) //遍历整个中缀表达式
{
if(c[i]=='(') //‘(’直接入栈
Push(c[i]);
else if(c[i]==')') //')'不断出栈,直到遇到‘(’
{
ch=Pop();
while(ch!='(')
{
res[k++]=ch;
ch=Pop();
}
}
else if(c[i]>='0'&&c[i]<='9')
res[k++]=c[i];
else
{
res[k++]='#';
while(top>-1&&rank[c[i]]<=rank[Stack[top]])
res[k++]=Pop();
Push(c[i]);
}
}
while(top>-1)
res[k++]=Pop();
}
//后缀表达式求值
void Operation(char res[]){
int i=0;
int t[2],n=-1;
while(i<k)
{
if(res[i]>='0'&&res[i]<='9') //数字字符转数字
{
n++;
t[n]=res[i]-48;
i++;
while(res[i]>='0'&&res[i]<='9')
{
t[n]=t[n]*10+res[i]-48;
i++;
}
}
else if(res[i]=='#')
i++;
else
{
switch(res[i]) //根据运算符进行运算
{
case '+': t[n-1]=t[n]+t[n-1]; n--;break;
case '-': t[n-1]=t[n-1]-t[n]; n--;break;
case '*': t[n-1]=t[n]*t[n-1]; n--;break;
case '/': t[n-1]=t[n-1]/t[n]; n--;break;
}
i++;
}
}
printf("运行结果为:%d",t[n]);
}
int main(){
char c[20],res[20];
int n;
n=Input(c);
InitialRank();
PostExpression(c,n,res);
Operation(res);
return 0;
}
运行结果: