中缀表达式:
中缀表达式(或中缀记法)是一个通用的算术或逻辑公式表示方法, 操作符是以中缀形式处于操作数的中间(例:3 + 4),中缀表达式是人们常用的算术表示方法。
后缀表达式:
不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则,如:(2 + 1) * 3 , 即2 1 + 3 *
算法思路:
·开始扫描;
·数字时,加入后缀表达式;
·运算符:
a. 若为 '(',入栈;
b. 若为 ')',则依次把栈中的的运算符出栈,加入后缀表达式中,直到出现'(',从栈中删除'(' ;
c. 若为 除括号外的其他运算符, 当其优先级高于除'('以外的栈顶运算符时,直接入栈。否则从栈顶开始,依次弹出比当前处理的运算符优先级高和优先级相等的运算符,直到一个比它优先级低的或者遇到了一个左括号为止。
·当扫描的中缀表达式结束时,栈中的的所有运算符出栈;
c语言代码如下:
#include <stdio.h>
#include <stdlib.h>
//中缀表达式求值
//先转为后缀表达式再求值;为简单起见,使用栈的循序存储结构实现
//栈的顺序存储结构,用一维数组实现
#define OK 1
#define ERROR -1
#define TRUE 1
#define FALSE 0
#define MAXSIZE 10
typedef int Status;
typedef char ElemType;
typedef struct {
ElemType data[MAXSIZE];
int top;//栈顶指针
}Stack;
//1. 初始化
Status InitStack(Stack *S){
int i;
for(i=0;i<MAXSIZE;i++)
S->data[i]=NULL;
S->top=-1;
return OK;
}
//2. 创建一个长度为n的堆栈
Status CreateStack(Stack *S,int n){
if(n>MAXSIZE || n<1){
printf("输入长度有误!\n");
return ERROR;
}
srand(time(0));
int i;
for(i=0;i<n;i++){
S->data[i]=rand()%100+1;
}
S->top=n-1;
return OK;
}
//3. 压栈操作
Status push(Stack *S,ElemType e){
if(MAXSIZE-1==S->top){
printf("栈已满\n");
return ERROR;
}
//栈顶指向的元素有值
++(S->top);
S->data[S->top]=e;
return OK;
}
//4. 出栈
Status pop(Stack *S,ElemType *e){
//将栈顶元素出栈,传给e
if(-1==S->top){
printf("栈为空!\n");
return ERROR;
}
*e=S->data[S->top];
--(S->top);
return OK;
}
//5. 中缀表达式转后缀表达式
void MidToFinal(char *mid,char *final){
//中缀表达式为middle,要转换成后缀表达式传给last
//新建一个栈,来存储符号
char e;
Stack S;
if(OK!=InitStack(&S)){
printf("初始化栈失败!\n");
}
//当带转换的字符串*mid未终止时,循环处理
while(*mid){
//如果是数字,则直接输出
if(*mid>='0' && *mid<='9'){
*(final++)=*(mid++);
continue;
}else if(*mid=='+' || *mid=='-' || *mid=='*' || *mid=='/' || *mid=='(' || *mid==')'){
//输入的是合法运算符号,比较之前是否有更高优先级的符号
if(S.top==-1 || '('==*mid){
//当符号栈为空或遇到左括号时,符号入栈
push(&S,*(mid++));
continue;
}
if(')'==*mid){
//遇到右括号时,栈顶元素依次出栈;直到遇到第一个左括号时结束
pop(&S,&e);
*(final++)=e;
while(pop(&S,&e) && e!='('){
*(final++)=e;
}
// printf("%c\n",e);
mid++;
continue;
}
//后续的处理都要取出临时的栈顶元素,与当前输入的符号*mid相比较;当临时栈顶元素优先级大于等于输入符号的优先级时,出栈;否则符号入栈(已经弹出一个,记得把弹出的元素也入栈)
pop(&S,&e);
if('+'==*mid || '-'==*mid){
if(e=='('){
push(&S,'(');
push(&S,*(mid++));
continue;
}else{
*(final++)=e;
push(&S,*(mid++));
continue;
}
}else if('*'==*mid || '/'==*mid){
if('*'==e || '/'==e){
*(final++)=e;
push(&S,*(mid++));
continue;
}else{
push(&S,e);
push(&S,*(mid++));
continue;
}
}
}else{
printf("输入的字符不合法!%c\n",*mid);
return ERROR;
}
}
//当待转换的字符已经结束时,符号栈至少还有一个元素(中缀表达式的特点:数字结尾;后缀表达式以符号结尾);将栈中的元素依次出栈
while(S.top!=-1){
pop(&S,&e);
*(final++)=e;
}
//字符串的结束符!
*final='\0';
}
int main()
{
/*
Stack S;
int i,n,e;
if(OK!=InitStack(&S)){
printf("初始化失败!");
return ERROR;
}
printf("输入初始化栈的长度n=");
scanf("%d",&n);
if(OK==CreateStack(&S,n)){
for(i=0;i<=S.top;i++){
printf("%d\t",S.data[i]);
}
}
printf("\n输入想要插入栈的值");
while(1==scanf("%d",&e)){
if(ERROR==push(&S,e)){
break;
}else{
for(i=0;i<=S.top;i++)
printf("%d\t",S.data[i]);
}
}
printf("\n接下来测试出栈!栈中的元素依次出栈\n");
while(OK==pop(&S,&e)){
getchar();
printf("%d\t",e);
}
*/
char data[]="3+(5*6-7/1*7)*9";
char final[]="";
MidToFinal(data,final);
printf("%s\n",final);
return 0;
}