zoukankan      html  css  js  c++  java
  • 7-20 表达式转换 (25分)

    题目链接:https://pintia.cn/problem-sets/15/problems/827

    参考:https://blog.csdn.net/SiKongPop/article/details/77972879#comments(内附数个测试样例)

    题意:

    将输入中缀表达式转换为后缀表达式,输入字符包含'+' '-' '*' '/' '(' ')'。输出的每个操作数或操作符用空格间隔开,并且末尾不能输出多余空格

    特别注意:操作数是可以有多位的,并且可以是小数,也就是说会包含有小数点,同时有的操作数是带符号的,带+号的不用输出+号,但是带-号的需要输出-号。

    如果不把这些考虑进去注意,会有格式错误。

    中缀到后缀的代码逻辑:

    先准备一个栈S用来存储操作符,然后对输入的表达式的每个字符逐个处理。

    对于输入的字符进行如下判断:

    1)如果是'('直接压入栈S。

    2)如果是'*' '/' '+' '-',将S的栈顶出栈输入的字符进行对比,如果输入操作符优先级小于等于栈顶操作符,则先输出栈顶操作符,再将输入的操作符压入栈S。

    3)如果是')',S出栈,判断出栈的字符是不是'(',如果不是,则输出,否则,直接退出判断

    处理多位数,小数以及带符号数的方法:

    1)首先要清楚什么地方会出现带符号的数,第一种情况是在输出结果的开头,比如“-2+1”第二种情况是在括号里面,即紧接着'(',例如“(-2+1)”或者“(-2)+1”

    2)如果(1)的条件满足,则顺着下去判断,逐个判断接下来输入的字符,如果仍然是数字或者小数点,就接着输出,如果遇到了非数字和非小数点的字符,就结束输出(此时一个操作数的输出已经完成,可以进行下一个输入的操作符的判断。)

    3)如果只是不带符号的数,那么也跟(2)一样,从第一个数字开始逐个判断下一个数,与(2)同理

    结果是如何输出的:

    1)对于操作数,读入之后按要求处理后直接输出即可。

    2)对于操作符一部分是在操作符入栈时优先级比栈顶操作符低级(或与栈顶操作符平级)的时候将栈顶操作符输出,剩下一部分在程序最后面,将剩下未出栈的操作符逐个出栈输出。

    AC代码:

      1 #include <iostream>
      2 #include <string>
      3 #include <cstring>
      4 using namespace std;
      5 
      6 class stack_//定义栈
      7 {
      8 public:
      9     stack_() :r(-1) {}
     10     ~stack_() {}
     11     void push(char k)
     12     {
     13         s[++r] = k;
     14     }
     15     char pop()
     16     {
     17         if (r != -1)
     18             return s[r--];
     19         else
     20             return '';//如果栈为空,就返回''
     21     }
     22 public:
     23     char s[1000];
     24     int r;
     25 };
     26 
     27 int main()
     28 {
     29     stack_ operate_;//用来存放操作符
     30        char exp_[1000];//用来接收输入的表达式
     31     int cnt = 0;//计数,若为0说明是所输出结果的第一个字符,每次输出之后自增
     32 
     33     cin.getline(exp_, 1000);//输入表达式
     34     for (int i = 0; i < 1000; i++)//遍历所输入表达式的每一个字符
     35     {
     36         if ('' == exp_[i])break;//遍历完成,退出循环
     37         //判断:+-号是不是在'('后一个,或者在开头。这是出现带符号数字的惟二条件:
     38         //即出现在开头或以类似(-2+3)的形式出现,这里对是不是符合两个条件进行判断
     39         if (
     40             (i == 0 && (exp_[i] == '-' || exp_[i] == '+')) ||
     41             (i >= 1 && ((exp_[i] == '-' || exp_[i] == '+') && exp_[i - 1] == '('))
     42             )//判断条件是否满足
     43         {
     44             if (exp_[i] == '-')//如果是符号是'-'
     45             {
     46                 if (cnt == 0)
     47                 {
     48                     cout << '-'; cnt++;//为输出的第一个字符,不需要输出空格,直接输出'-',cnt自增
     49                 }
     50                 else
     51                 {
     52                     cout << ' ' << '-'; //若非第一个字符,则在前面先输出一个空格,因为cnt已不为0,不自增也可以
     53                 }
     54             }
     55             else if (exp_[i] == '+')//类似上面
     56             {
     57                 if (cnt == 0)cnt++;//注意此处,虽然并没有输出,但也要自加,否则输出完下面数字后的再下一次输出,会被误认为是第一次输出   
     58                 else
     59                 {
     60                     cout << ' '; //如果不是第一个,就只输出空格,因为+号是不用输出的
     61                 }
     62             }
     63 
     64             int j;
     65             for (j = i + 1;; j++)
     66             {
     67                 if ((exp_[j] >= '0' && exp_[j] <= '9') || exp_[j] == '.')
     68                 {
     69                     cout << exp_[j];//cnt不用自增,因为上面输出符号的时候已经处理过cnt了,
     70                     //此处输出数字的时候可以不考虑是第一次输出的情况
     71                 }
     72                 else break;//如果遇到的字符不是数字或者小数点,就可以结束此次输出
     73             }
     74             j--;//此时数组j下标放的是继上一次输出数字后的第一个非数字或小数点字符
     75             //下次循环理应从这里开始判断,但是因为进入下一次循环i要++,所以这里先--一次
     76             //抵消掉一次++,再赋给i
     77             i = j;
     78             continue;//下一次循环,开始下一个字符的判断
     79         }
     80         //判断输入字符是不是数字,此处
     81         else if (exp_[i] >= '0' && exp_[i] <= '9')
     82         {//逻辑与上面一个if类似
     83             if (cnt == 0)
     84             {
     85                 cout << exp_[i]; cnt++;
     86             }
     87             else
     88             {
     89                 cout << ' ' << exp_[i];
     90             }
     91             int j;
     92             for (j = i + 1;; j++)
     93             {
     94                 if ((exp_[j] >= '0' && exp_[j] <= '9') || exp_[j] == '.')
     95                 {
     96                     cout << exp_[j];
     97                 }
     98                 else break;
     99             }
    100             j--;
    101             i = j;
    102             continue;
    103         }
    104         //判断输入字符是不是'('
    105         else if (exp_[i] == '(')
    106         {
    107             operate_.push(exp_[i]);//如果是,可以直接压入栈
    108             continue;//下一次循环,继续判断下一个输入的字符
    109         }
    110         //判断是不是输入'*'或'/',注意''里面只能含有操作符,
    111         //不能带空格,否则判断的时候会出现错误
    112         else if (exp_[i] == '*' || exp_[i] == '/')
    113         {
    114             while (1)
    115             {
    116                 char ch = operate_.pop();
    117                 if (ch != '')//如果不是空栈
    118                 {
    119                     if (ch != '/' && ch != '*')//如果不是'/'或'*',说明栈顶操作符是优先级更低的,直接压入栈即可
    120                     {
    121                         operate_.push(ch);//先将刚刚出栈的栈顶元素重新压回栈
    122                         operate_.push(exp_[i]);//再将操作符'*'或'/'压入
    123                         break;
    124                     }
    125                     else//若遇到优先级相同的,先输出旧的,再压入新的
    126                     {
    127                         if (cnt == 0)
    128                         {
    129                             cout << ch; cnt++;
    130                         }
    131                         else
    132                             cout << ' ' << ch;
    133                         continue;
    134                     }
    135                 }
    136                 else//空栈
    137                 {
    138                     operate_.push(exp_[i]);
    139                     break;
    140                 }
    141             }
    142         }
    143         //判断'+'或'-'
    144         else if (exp_[i] == '+' || exp_[i] == '-')//逻辑同上
    145         {
    146             while (1)
    147             {
    148                 char ch = operate_.pop();
    149                 if (ch != '')
    150                 {
    151                     if (ch != '/' && ch != '*' && ch != '+' && ch != '-')
    152                     {
    153                         operate_.push(ch);
    154                         operate_.push(exp_[i]);
    155                         break;
    156                     }
    157                     else
    158                     {
    159                         if (cnt == 0)
    160                         {
    161                             cout << ch; cnt++;
    162                         }
    163                         else
    164                             cout << ' ' << ch;
    165                         continue;
    166                     }
    167                 }
    168                 else
    169                 {
    170                     operate_.push(exp_[i]);
    171                     break;
    172                 }
    173             }
    174         }
    175         //判断')'
    176         else if (exp_[i] == ')')
    177         {
    178             char ch;
    179             while (1)
    180             {
    181                 ch = operate_.pop();
    182                 if (ch != '')//如果不为空栈
    183                 {
    184                     if (ch != '(')//若没有遇到'(',直接输出出栈的元素
    185                     {
    186                         if (cnt == 0)
    187                         {
    188                             cout << ch; cnt++;
    189                         }
    190                         else
    191                             cout << ' ' << ch;
    192                         continue;
    193                     }
    194                     else
    195                     {
    196                         break;//如果所出栈的字符是'(',则停止出栈
    197                     }
    198                 }
    199                 else//如果是空栈,直接退出
    200                 {
    201                     break;
    202                 }
    203             }
    204         }
    205     }//big for      
    206     //此处将没有出栈的操作符全部出栈
    207     while (operate_.r != -1)
    208     {
    209         char ch = operate_.pop();
    210         if (cnt == 0)
    211         {
    212             cout << ch; cnt++;
    213         }
    214         else
    215             cout << ' ' << ch;
    216     }
    217     return 0;
    218 }
    AC代码:

     

  • 相关阅读:
    希尔排序
    代理模式
    快速排序
    插入排序
    各种排序算法的稳定性和复杂度
    简单选择排序
    冒泡排序
    流程图
    PLAY学习【未完】
    项目之maven心得
  • 原文地址:https://www.cnblogs.com/2020R/p/12398422.html
Copyright © 2011-2022 走看看