逆波兰式

来源:互联网 发布:天使与魔鬼知乎 编辑:程序博客网 时间:2024/04/28 08:25
逆波兰式也叫后缀表达式(将运算符写在操作数之后)
如:我们平时写a+b,这是中缀表达式,写成后缀表达式就是:ab+
(a+b)*c-(a+b)/e的后缀表达式为:
(a+b)*c-(a+b)/e
→((a+b)*c)((a+b)/e)-
→((a+b)c*)((a+b)e/)-
→(ab+c*)(ab+e/)-
→ab+c*ab+e/-
将一个普通的中序表达式转换为逆波兰表达式的一般算法是:
1)首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。
(2)读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多加上了优先级最低的特殊符号“#”。
(3)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析到该数字串的结束并将该数字串直接输出。
(4)如果不是数字,该字符则是运算符,此时需比较优先关系。
做法如下:将该字符与运算符栈顶的运算符的优先关系相比较。如果,该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。倘若不是的话,则将栈顶的运算符从栈中弹出,直到栈顶运算符的优先级低于当前运算符,将该字符入栈。
(5)重复上述操作(1)-(2)直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,我们便可以将中缀式表示的简单算术表达式转化为逆波兰表示的简单算术表达式。


typedef int SElemType;

typedef struct SqStack

{ char *base;

char *top;

char stacksize;

}SqStack;

程序

void InitStack (SqStack &S)

{

S.base=(char *) malloc (STACK_INIT_SIZE *sizeof(char));

if (!S.base)

exit (OVERFLOW); //为栈S分配存储空间失败

S.top=S.base;

S.stacksize=STACK_INIT_SIZE;

}

int Push(SqStack &S,char ch)

// 将元素e插入到栈S中,成为新的栈顶元素

{

if (S.top-S.base>S.stacksize) //Stack==full?

{ S.base=(char *)realloc(S.base,(S.stacksize+STACKINCREMENT *sizeof(char)));

if (!S.base)

{ printf(“Failure to reallocate the Memory units!:/n”);

exit(OVERFLOW);

}

S.top=S.base+S.stacksize; //To Modify pointer of Satck top

S.stacksize+=STACKINCREMENT; //To modify the size of stack

} // end of if

*S.top++=ch; //先将e送入栈顶指针所指向的单元,再将栈顶指针加1

return(OK);

} //end of Push() subfunction

int Pop(SqStack &S,char &ch)

{

if (S.top==S.base)

{

printf(“下溢!”);

return (ERROR);

}

ch=*--S.top;

return (OK);

}

void Translation()

{//将算术表达式转化为逆波兰表达式,num为算术表达式的字符总个数

int i,j;

char str[100],exp[100],ch;

SqStack S;

InitStack(S);

i=1;

printf(“ 请输入算术表达式字符串,求其逆波兰表达式,以#为结束标志,如a-b*c/(3+6)#:/n”);

do

{

scanf(“%c”,&str);

i++;

}while(str[i-1]!=’#’);

str[0]=’(‘; //将表达式放在()内

str[i-1]=’)’;

str=’#’;

i=0;

j=0;

while(str!=’#’)

{ if((str>=’0’ &&str<=’9’)||(str>=’a’ &&str<=’z’))

{

exp[j]=str;

j++;

} //end of if

else if(str==”(”)

Push(S.str);

else if(str==’)’)

{ while(*(S.top-1)!=’(’)

//将S中左括弧“(”以前的所有字符依次弹出并存入数组exp中

{ Pop(S,ch); exp[j]=ch; j++; }

S.top--;

} //end of elseif

else if(str==’+’||str==’-’) //如果判定为“+”号或“-”号,则做如下操作

{ while((s.top!=S.base)&&(*(S.top-1)!=’(’))

//将S中左括弧“(”以前字符依次弹出并存入数组exp 中

{ Pop(S,ch); exp[j]=ch; j++; }

Push(S,str);

} //end of else if

else if (str==’*’||str==’/’)

{

while((*(S.top-1)==’*’)||(*(S.top-1)==’/’))

{ Pop(S,ch); exp[j]=ch; j++; }

Push(S,str);

} //end of else if

i++;

} //end of while

exp[j]=’#’;

printf(“/n/n输入的算术表达式”);

i=1;

while(str[i+1]!=’#’)

{ printf(“%c”,str);

i++;

} //end of while

printf(“ 逆波兰表达式为:/n”);

i=0;

while(exp!=’#’)

{ printf(“%c”,exp); i++; }
}
void main()
{
Translation();
printf(“/n”);
printf(“…OK…!”)
getch();
}

还有一种方法,用2叉树.