逆波兰式

 

 

逆波兰式

Description

假设表达式由单字母变量和双目四则运算符构成,试编写程序,将一个通常书写形式且书写正确的表达式转换为逆波兰式。

Input

输入由单字母变量和双目四则运算算符构成的表达式。

Output

输出其逆波兰式。

Sample Input       (a+b)*c

Sample Output    ab+c*

 

更多测试用例如下:

输入a*b+(c-d/e)*f                      输出ab*cde/-f*+

输入a+b*(c-d)-e/f                      输出 abcd-*+ef/-

输入a*(b*(c+d/e)-f)                    输出abcde/+*f-*

/*逆波兰表示法,是一种逻辑、算术和代数表示方法,
其特点是操作符置于操作数的前面,因此也称为前缀表示法。
例如:“a+b”的波兰表示法为:“+ab”。
逆波兰表示法是一种数学表达式方式,在逆波兰记法中,所有操作符置于操作数的后面,因此也称为后缀表示法。
例如:“a+b”的逆波兰表示法为:“ab+”。
题目要求将输入的波兰表示法表达式转换为逆波兰表示法表达式。 */
/*基本思想:首先需要分配2个栈,一个作为临时存储运算符的栈S1 OPTR(含一个结束符号),
一个作为输入逆 波兰式的栈S2(空栈),S1栈可先放入优先级最低的运算符#,
注意,中缀式应以此最低优先级的运算符结束。可指定其他字符,不一定非#不可。
从中缀式的左端开始取字符,逐序进行如下步骤:
(1)若取出的字符是 操作数,则分析出完整的运算数,该操作数直接送入S2栈
(2)若取出的字符是 运算符,则将该运算符与S1栈栈顶元素比较,如果该 运算符优先级大于S1栈栈顶 运算符优先级,则将该运算符进S1栈,
否则,将S1栈的栈顶运算符弹出,送入S2栈中,直至S1栈栈顶运算符低于(不包括等于)该运算符优先级,则将该运算符送入S1栈。
(3)若取出的字符是“(”,则直接送入S1栈底。
(4)若取出的字符是“)”,则将距离S1栈栈底最近的“(”之间的运算符,逐个 出栈,依次送入S2栈,此时抛弃“(”。
(5)重复上面的1~4步,直至处理完所有的输入字符
(6)若取出的字符是“#”,则将S1栈内所有运算符(不包括“#”),逐个 出栈,依次送入S2栈。
完成以上步骤,S2栈便为逆 波兰式输出结果。不过S2应做一下逆序处理。便可以按照逆 波兰式的计算方法计算了!*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define Stack_Size 100
typedef struct
{
    char elem[Stack_Size];
    int top;
}SeqStack;
void chushi(SeqStack *S)
{
    S->top=-1;
}
int push(SeqStack *S,char x)
{
    if(S->top==Stack_Size-1)return 0;
    S->top++;
    S->elem[S->top]=x;
    return 1;
}
int pop(SeqStack *S,char *x)
{
    if(S->top==-1)
        return 0;
    else
        {
    *x=S->elem[S->top];
    S->top--;
    return 1;
        }
}
char GetTop(SeqStack *S)
{
    if(S->top==-1)
    return 0;
        else
        {
            return  (S->elem[S->top]);
        }
}
int isempty(SeqStack *S)
{
    if(S->top==-1)return 1;
    else return 0;
}
void nibolan(char *ch)
{   SeqStack s1;SeqStack s2;
    chushi(&s1);
    chushi(&s2);
    push(&s1,'#');
    char x,p;int i;int j=0;int c[100];
    for(i=0;(ch[i]!='\0');i++)
    {   switch(ch[i])
     {
        case'(':push(&s1,ch[i]);break;
        case')':
            while(GetTop(&s1)!='(')
            {
                pop(&s1,&x);
                push(&s2,x);
            }
            pop(&s1,&x);break;
        case'+':
        case'-':
        while ((GetTop(&s1) != '#')&&(GetTop(&s1) != '('))
            {
                pop(&s1,&x);
                push(&s2,x);
            }
            push(&s1,ch[i]);
            break;
        case'*':
        case'/':
       while (GetTop(&s1) == '*' || GetTop(&s1) == '/')
            {
                pop(&s1,&x);
                push(&s2,x);
            }
            push(&s1,ch[i]);
            break;
       default:
            push(&s2,ch[i]);
     }
  }
  while((!isempty(&s1))&&(GetTop(&s1)!='#'))
  { //若栈s1不为空,将其中的元素依次弹出到s2
      pop(&s1,&x);
      push(&s2,x);
  }



while(!isempty(&s2))
    { //栈未空,将栈低元素依次弹出
        pop(&s2,&p);
        c[j++] = p;
    }
    c[j]='\0';
     for(i=j-1;i>=0;i--)
     {
         printf("%c",c[i]);
     }
}
int main()
{
    char ch[100];
    scanf("%s",ch);
    nibolan(ch);
    return 0;
}

 

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值