中缀表达式,后缀表达式,前缀表达式2008-12-19 16:47中缀表达式:运算符放在两个运算对象中间,如:(2+1)*3;
后缀表达式:不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则,如:2 1 + 3 *;
前缀表达式:同后缀表达式一样,不包含括号,运算符放在两个运算对象的前面,如:* + 2 1 3。
(2)表达式的计算:
由于后缀表达式中没有括号,不需判别优先级,计算严格从左向右进行,故计算一个后缀表达式要比计算机一个中缀表达式简单得多。
将中缀表达式转换为后缀表达式的算法思想:
·当读到数字直接送至输出队列中
·当读到运算符t时,
a.将栈中所有优先级高于或等于t的运算符弹出,送到输出队列中;
b.t进栈
·读到左括号时总是将它压入栈中
·读到右括号时,将靠近栈顶的第一个左括号上面的运算符全部依次弹出,送至输出队列后,再丢弃左括号。
下面是一个将中缀表达式转换为后缀表达式并求值的一个c语言的例子
/*将中缀表达式转换为后缀表达式并求值*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
typedef struct /*定义一个用于存储字符集合的栈*/
{
char elements[MAX];
int top;
}
STACK_char;
typedef struct /*定义一个用于存储浮点数集合的栈*/
{
float elements[MAX];
int top;
}
STACK_num;
/*以下为栈的基本操作函数*/
void MakeNull_char(STACK_char *);
char Top_char(STACK_char *);
char PopAddTop_char(STACK_char *);
void Push_char(char,STACK_char *);
void MakeNull_num(STACK_num *);
float Top_num(STACK_num *);
float PopAddTop_num(STACK_num *);
void Push_num(float,STACK_num *);
int compare(char,char); /*比较运算符优先级的函数*/
void change(char *,char *); /*将中缀表达式转换为后缀表达式的函数*/
float compute(char *); /*对后缀表达式进行运算的函数*/
int main()
{
char a[MAX],b[MAX];
float result;
printf("请输入一个表达式:/n");
gets(a);
change(a,b);
printf("后缀表达式为:/n%s/n",b);
result=compute(b);
printf("运算结果为:/n%.3f",result);
getchar();
return 0;
}
/*以下定义操作函数*/
void MakeNull_char(STACK_char *S) /*此函数将栈初始化为空栈*/
{
(*S).top=MAX;
}
char Top_char(STACK_char *S) /*此函数返回栈顶元素*/
{
return (*S).elements[(*S).top];
}
char PopAddTop_char(STACK_char *S) /*此函数返回栈顶元素并删除栈顶元素*/
{
(*S).top=(*S).top+1;
return (*S).elements[(*S).top-1];
}
void Push_char(char x,STACK_char *S) /*此函数将将一元素压入栈中*/
{
(*S).top=(*S).top-1;
(*S).elements[(*S).top]=x;
}
void MakeNull_num(STACK_num *S)
{
(*S).top=MAX;
}
float Top_num(STACK_num *S)
{
return (*S).elements[(*S).top];
}
float PopAddTop_num(STACK_num *S)
{
(*S).top=(*S).top+1;
return (*S).elements[(*S).top-1];
}
void Push_num(float x,STACK_num *S)
{
(*S).top=(*S).top-1;
(*S).elements[(*S).top]=x;
}
int compare(char x,char y) /*此函数比较运算符优先级*/
{
if ((x=='*'||x=='/'||x=='%')&&(y=='+'||y=='-'))
return 1;
else
return 0;
}
void change(char *a,char *b) /*此函数将中缀表达式转换为后缀表达式*/
{
char num[12]="0123456789.";
char c[2],d[2]; /*定义两个字符串,用于下面字符串比较*/
STACK_char S;
int i,k;
MakeNull_char(&S);
Push_char('#',&S);
k=0;
for (i=0;i<strlen(a);i++)
{
c[0]=a[i];
c[1]='/0';
d[0]=a[i+1];
d[1]='/0';
if (a[i]==' ') /*输入过程遇空格跳过*/
continue;
else if (strstr(num,c)) /*比较字符串以确定当前字符是否为数字*/
{
b[k]=a[i];
k++;
if (i==strlen(a)-1)
{
b[k]=' ';
k++;
}
else if (strstr(num,d)==NULL) /*运算符后加空格*/
{
b[k]=' ';
k++;
}
}
else
{
if (a[i]!=')')
{
if (a[i]=='(') /*遇‘(’压入栈*/
Push_char(a[i],&S);
else if (compare(a[i],Top_char(&S))||Top_char(&S)=='#') /*优先级高于栈顶元素压入栈*/
Push_char(a[i],&S);
else
{
while (compare(a[i],Top_char(&S))==0&&Top_char(&S)!='#'&&Top_char(&S)!='(') /*优先级低于栈顶元素直接输出*/
{
b[k]=PopAddTop_char(&S);
k++;
b[k]=' ';
k++;
}
Push_char(a[i],&S);
}
}
else
{
while (Top_char(&S)!='(') /*遇‘)’向前查找第一个‘(’并输出其间运算符*/
{
b[k]=PopAddTop_char(&S);
k++;
b[k]=' ';
k++;
}
PopAddTop_char(&S);
}
}
}
while (Top_char(&S)!='#') /*依次输出剩余运算符*/
{
b[k]=PopAddTop_char(&S);
k++;
b[k]=' ';
k++;
}
b[k-1]='/0'; /*字符串后加‘/0’结束*/
}
float compute(char *b) /*计算后缀表达式的值*/
{
float result;
float integer=0,decimal=0; /*定义变量,表示整数、小数部分*/
float m=1;
float t=0.1;
float top,second;
STACK_num L;
int i;
i=0;
MakeNull_num(&L);
while (b[i]!='/0')
{
while (b[i]!=' '&&b[i]!='.'&&b[i]!='+'&&b[i]!='-'&&b[i]!='*'&&b[i]!='/'&&b[i]!='+'&&b[i]!='%') /*对整数部分进行运算*/
{
integer=integer*m+b[i]-48;
m*=10;
i++;
}
if (b[i]=='.') /*对小数部分进行运算*/
{
i++;
while (b[i+1]!=' '&&b[i+1]!='/0')
{
i++;
decimal+=(b[i]-48)*t;
t*=0.1;
}
decimal+=(b[i]-48)*t;
t*=0.1;
i++;
}
integer+=decimal;
if (b[i]==' '&&b[i-1]!='+'&&b[i-1]!='-'&&b[i-1]!='*'&&b[i-1]!='/'&&b[i-1]!='+'&&b[i-1]!='%') /*将一个完整操作数进行压栈*/
{
Push_num(integer,&L);
m=1;
t=0.1;
integer=0;
decimal=0;
}
switch (b[i]) /*对不同运算符进行分别处理*/
{
case'+':
top=PopAddTop_num(&L);
second=Top_num(&L);
result=top+second;
PopAddTop_num(&L);
Push_num(result,&L);
break;
case'-':
top=PopAddTop_num(&L);
second=Top_num(&L);
result=second-top;
PopAddTop_num(&L);
Push_num(result,&L);
break;
case'*':
top=PopAddTop_num(&L);
second=Top_num(&L);
result=top*second;
PopAddTop_num(&L);
Push_num(result,&L);
break;
case'/':
top=PopAddTop_num(&L);
second=Top_num(&L);
result=second/top;
PopAddTop_num(&L);
Push_num(result,&L);
break;
case'%':
top=PopAddTop_num(&L);
second=Top_num(&L);
result=(int)second%(int)top;
PopAddTop_num(&L);
Push_num(result,&L);
break;
}
i++;
}
return Top_num(&L);
}