• 蓝桥杯 算法训练 ALGO-57 删除多余括号


    算法训练 删除多余括号  
    时间限制:1.0s   内存限制:512.0MB
    问题描述
      从键盘输入一个含有括号的四则运算表达式,要求去掉可能含有的多余的括号,结果要保持原表达式中变量和运算符的相对位置不变,且与原表达式等价,不要求化简。另外不考虑'+' '-'用作正负号的情况,即输入表达式不会出现(+a)或(-a)的情形。
    输入格式
      表达式字符串,长度不超过255,  并且不含空格字符。表达式中的所有变量都是单个小写的英文字母, 运算符只有加+减-乘*除/等运算符号。
    输出格式
      去掉多余括号后的表达式
    样例输入
    样例一:
    a+(b+c)-d
    样例二:
    a+b/(c+d)
    样例三:
    (a*b)+c/d
    样例四:
    ((a+b)*f)-(i/j)

     样例输出样例一:

    a+b+c-d
    样例二:
    a+b/(c+d)
    样例三:
    a*b+c/d
    样例四:
    (a+b)*f-i/j

    题目解析:

      本道题其实化简表达式,这是我们小学学到的内容,即题目中写到:结果要保持原表达式中变量和运算符的相对位置不变,且与原表达式等价,不要求化简。

      遍历输入的表达式,如果发现左括号,则找到与它对应的右括号,并根据括号左右及中间内容分情况处理该括号是否可以删除。在递归地处理过程中,如果又发现了括号,则先处理发现的这个括号是否可以删除,处理结束后,返回上一个括号,继续递归处理,直至所有的括号处理完成。

      有以下几种情况括号是不可以删除的:

    1. 括号前边为 “ - ”,且括号中为 “ + ” 或 “ - ”,不能删除;
    2. 括号前边为 “ / ”,不能删除;
    3. 括号后为 “ * ”,且括号中为 “ + ” 或 “ - ”,不能删除;

      有以下几种情况是可以删除:

    1. 括号前和后为 “ + ” 或 “ - ”,括号中为 “ + ” 或 “ - ” 或 “ * ” 或 “ / ”,可以删除,但是注意:若括号前为 “ - ”,括号中为 “ + ” 或  “ - ”,在前边已经处理了,所以可以排除这种情况;
    2. 括号前为 “ * ”,括号中为 “ * ” 或 “ / ”,括号后为 “ + ” 或 “ - ” 或 “ * ” 或 “ / ”,可以删除;

      其他情况不能删除。

    示例代码:

     1 #include<stdio.h>
     2 
     3 //检测括号是否可以删除 
     4 int check(char s[], int left, int right)
     5 {
     6     int i;            //下标 
     7     int leftCount;    //左括号统计 
     8     
     9     //处理 ' -(a +|- b) ' 
    10     if (s[left-1] == '-')
    11     {
    12         i = left;
    13         leftCount = 1;
    14         while (++i < right) {
    15             if (s[i] == '(')
    16             {
    17                 leftCount++;
    18             }
    19             else if ((s[i] == '+' || s[i] == '-' ) && leftCount == 1)
    20             {
    21                 return 0;
    22             }
    23         }
    24     }
    25     
    26     //处理 ' /(a +|-|*|/ b) ' 
    27     if (s[left-1] == '/')
    28     {
    29         return 0;
    30     }
    31     
    32     //处理 ' +(a +|-|*|/ b) +|- ' 
    33     if (s[left-1] != '*' && s[left-1] != '/' &&
    34         s[right+1] != '*' && s[right+1] != '/')
    35     {
    36         return 1;
    37     }
    38     
    39     //处理 ' *(a *|/ b) +|-|*|/ ' 
    40     i = left;
    41     leftCount = 1;
    42     while (++i < right) {
    43         if (s[i] == '(')
    44         {
    45             leftCount++;
    46         }
    47         else if ((s[i] == '*' || s[i] == '/' ) && leftCount == 1)
    48         {
    49             return 1;
    50         }
    51     }
    52     return 0;
    53 }
    54 
    55 //删除多余的括号 
    56 int delExcessBrackets(char s[], int index)
    57 {
    58     int left, right;
    59     while (s[index] != '') {
    60         if (s[index] == ')')     //如果为右括号,返回下标 
    61         {
    62             return index;    
    63         }
    64         if (s[index] == '(')     //如果为左括号,找到右括号的下标 
    65         {
    66             left = index;
    67             index = right =  delExcessBrackets(s, index+1);
    68             
    69             if (check(s, left, right))    //若检测结果为可以删除,那么把括号位置换成空 
    70             {
    71                 s[left] = s[right] = ' '; 
    72             }
    73         }
    74         index++;
    75     }        
    76 } 
    77 
    78 int main()
    79 {
    80     char exp[256];
    81     scanf("%s", exp);
    82     
    83     delExcessBrackets(exp, 0);
    84     
    85     int i = -1;
    86     while (exp[++i] != '') {
    87         if (exp[i] != ' ')
    88         {
    89             printf("%c", exp[i]);
    90         }
    91     }
    92     
    93     return 0;
    94 }
  • 相关阅读:
    socat + kata + cgroup
    2018-8-10-卷积神经网络全面解析
    2019-8-31-PowerShell-通过-WMI-获取系统服务
    2019-8-31-PowerShell-通过-WMI-获取系统服务
    2018-2-13-不使用数据结构反转栈
    统计难题
    Keywords Search
    [JSOI2008]最大数
    Android(java)学习笔记1:多线程的引入
    欢迎使用CSDN-markdown编辑器
  • 原文地址:https://www.cnblogs.com/cao-lei/p/7236051.html
Copyright © 2020-2023  润新知