zoukankan      html  css  js  c++  java
  • 中缀表达式到后缀表达式 (Data_Structure)

    描述

    我们熟悉的表达式如a+b、a+b*(c+d)等都属于中缀表达式。中缀表达式就是(对于双目运算符来说)操作符在两个操作数中间:num1 operand num2。同理,后缀表达式就是操作符在两个操作数之后:num1 num2 operand。ACM队的“C小加”正在郁闷怎样把一个中缀表达式转换为后缀表达式,现在请你设计一个程序,帮助C小加把中缀表达式转换成后缀表达式。为简化问题,操作数均为个位数,操作符只有+-*/ 和小括号。

     
    输入
    第一行输入T,表示有T组测试数据(T<10)。
    每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个表达式。这个表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。数据保证输入的操作数中不会出现负数。并且输入数据不会出现不匹配现象。
    输出
    每组输出都单独成行,输出转换的后缀表达式。
    样例输入
    2
    1+2
    (1+2)*3+4*5
    样例输出
    12+
    12+3*45*+

    思路:

           用一个栈存放符号,用一个队列存放数(因为后缀数的顺序和中缀数的顺序一致)。判断优先级,“+,-”赋值为1,“*,/”赋值为2,“(”赋值为3,“)”赋值为0.

           特别注意“(”进栈后,优先级就最低了,到时一个if()特殊对待下就行。

           如果是数,就进队列;如果是符号。优先级比较,如果栈空,直接进栈,如果栈不空并且新的符号比栈顶符号优先级大,则进栈,否则说明要进行一个运算了。则进行一次部分出结果(先将队列中的数弄出来,再从栈中出符号,出符号要特别注意,分当前符号是“)”,当前符号不是“)”两种情况讨论),具体细节见代码注释。

    代码:

    #include<iostream>
    #include<stack>
    #include<queue>
    #include<cstring>
    #include<cstdio>
    using namespace std;

    stack<char> op;
    queue<char> num;
    char ch[1001];
    bool is_op(char a);
    int fun(char a);

    int main()
    {
    int T,i,len;
    char c;
    cin>>T;

    do
    {
    scanf("%s",ch);
    len = strlen(ch);

    for(i = 0 ; i < len ; ++i)
    {
    if(!is_op(ch[i]))//不是符号
    num.push(ch[i]);
    else//是符号
    {
    if(op.empty())
    op.push(ch[i]);
    else//符号栈里有符号
    {
    if(ch[i] != ')')//新符号不是右括号
    {
    if( op.top() == '(' || fun(op.top()) < fun(ch[i]) )
    op.push(ch[i]);
    else
    {
    while( !num.empty())
    {
    cout<<num.front(); num.pop();
    }
    if(!op.empty())
    {
    cout<<op.top(); op.pop();
    }
    --i;
    }

    }//if()不是右括号
    else//新括号是右括号
    {

    while( !num.empty())
    {
    cout<<num.front(); num.pop();
    }
    while( !op.empty() )
    {
    if(op.top() != '(')
    {
    c = op.top();
    cout<<op.top(); op.pop();

    }
    else
    {
    op.pop();//去掉那个“(”

    if(!op.empty())
    {

    if( op.top() != '(' && fun(op.top()) > fun(c) )
    {
    cout<<op.top();op.pop();
    break;
    }
    else
    break;
    }
    }

    }

    }
    }

    }//else是符号

    }//for(i)

    while(!num.empty())
    {
    cout<<num.front(); num.pop();
    }
    while(!op.empty())
    {
    cout<<op.top(); op.pop();
    }

    cout<<endl;
    }while(--T);

    // system("pause");
    return 0;
    }

    bool is_op(char a)
    {
    if(a=='+'||a=='-'||a=='*'||a=='/'||a=='('||a==')')
    return true;
    else
    return false;
    }

    int fun(char a)
    {
    switch(a)
    {
    case '+':
    case '-':return 1;break;
    case '*':
    case '/':return 2;break;
    case '(':return 3;break;
    default:return 0;break;
    }
    }
  • 相关阅读:
    10 行 Python 代码,批量压缩图片 500 张,简直太强大了
    听说苏州是互联网的荒漠,真的吗?
    sum() 函数性能堪忧,列表降维有何良方?
    len(x) 击败 x.len(),从内置函数看 Python 的设计思想
    如何给列表降维?sum()函数的妙用
    Shell脚本关于循环的一些总结
    大技霸教你远程执行Linux脚本和命令
    老板对我说,你要是能找出公司里摸鱼的人,我就给你涨薪!于是我写了两个脚本……
    Linux 命令行下搜索工具大盘点,效率提高不止一倍!
    饿了么总监分享:我是如何完成从程序员到管理层的蜕变?
  • 原文地址:https://www.cnblogs.com/HpuAcmer/p/2299894.html
Copyright © 2011-2022 走看看