蓝桥杯 算法训练 ALGO-156 表达式计算

算法训练 表达式计算

时间限制:1.0s   内存限制:256.0MB

问题描述

  输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。

输入格式

  输入一行,包含一个表达式。

输出格式

  输出这个表达式的值。

样例输入

1-2+3*(4-5)

样例输出

-4

数据规模和约定

  表达式长度不超过100,表达式运算合法且运算过程都在int内进行。

题目解析:

  运算优先级: 括号 → 乘除 → 加减

  例如  1-2+3*(4-5)

    (1)计算(4-5),表达式变为  1-2+3*-1

    (2)计算 3*-1,表达式变为  1-2+-3

    (3)计算 1-2,表达式变为  -1+-3

    (4)计算 -1+-3,表达式变为  -4

    (5)结果  -4

  根据这一规律,我们首先在输入的表达式两端加上括号,使程序变为重复去计算括号中的子表达式。计算规则如同上例。   

示例代码:

  1 import java.io.BufferedReader;
  2 import java.io.IOException;
  3 import java.io.InputStreamReader;
  4
  5 public class Main {
  6     public static void main(String[] args) throws IOException {
  7         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  8         StringBuilder expression = new StringBuilder("("+br.readLine()+")");    //表达式,在输入的表达式两边加上括号
  9         StringBuilder temp = new StringBuilder();                                //存放临时表达式,即每次存放的都是任意一个括号中的子表达式
 10         while(true){
 11             int frontBrackets = expression.lastIndexOf("(");            //从表达式后边开始搜索,找到最后一个"("
 12             int backBrackets = expression.indexOf(")", frontBrackets);  //从最后一个"("的位置开始往后搜索,找到与之对应的")"
 13
 14             if(frontBrackets == -1)    break;    //若再无表达式需要计算,即expression只有一个整数时,跳出循环
 15
 16             temp.append(expression.substring(frontBrackets + 1 , backBrackets));    //将此括号中的表达式存入temp
 17             expression.delete(frontBrackets, backBrackets + 1);        //在原始表达式中将括号连同其中的表达式删除
 18
 19             for(int i = 0; i < temp.length(); i++){        //从子表达式中找出运算符,根据运算原则,先乘除后加减
 20                 if(temp.charAt(i) == ‘*‘){                //若找到 "*" ,调用calculation进行运算
 21                     calculation(temp , ‘*‘ , i);
 22                     i = 0;                                //运算完后,i清零,方便下一次从开始位置继续寻找乘除运算符
 23                 }
 24
 25                 if(temp.charAt(i) == ‘/‘){
 26                     calculation(temp , ‘/‘ , i);
 27                     i = 0;
 28                 }
 29             }
 30
 31             for(int i = 0; i < temp.length(); i++){        //找完乘除运算符后,开始找加减云算符
 32                 if(temp.charAt(i) == ‘+‘){
 33                     calculation(temp , ‘+‘ , i);
 34                     i = 0;
 35                 }
 36
 37                 if(temp.charAt(i) == ‘-‘){
 38                     calculation(temp , ‘-‘ , i);
 39                     i = 0;
 40                 }
 41             }
 42
 43             expression.insert(frontBrackets, temp);        //运算完后,将结果插入在刚才删除的括号位置,构成新的表达式,继续循环计算
 44             temp.delete(0, temp.length());                //将temp清空,方便下一个表达式计算
 45
 46         }
 47
 48         System.out.println(expression);        //输出结果
 49     }
 50
 51     /**
 52      * 计算表达式
 53      * @param src      表达式
 54      * @param op       操作符
 55      * @param location    操作符在表达式中的位置
 56      */
 57     private static void calculation(StringBuilder src, char op, int location) {
 58         int x = 0;    //操作数1
 59         int y = 0;  //操作数2
 60         int sum = 0;// sum = x (op) y
 61
 62         String check = "0123456789+-";    //检测运算符两边的内容是否为其中数组或者正数或负数
 63         StringBuilder temp = new StringBuilder();    //存放运算符两边的字符
 64
 65         if(location == 0)    return;        //若遇到子表示其中只有加减运算符这种情况,且遇到的第一个运算符其实是想表示一个正数或者负数的符号,则函数返回,继续寻找下一个运算符
 66
 67         int k = 0;  //搜索操作符左右两边的数
 68         for(k = location - 1; k >= 0 && check.contains(src.charAt(k) + ""); k--){    //从运算符左边一个位置开始往前搜索,找到第一个操作数
 69             try{
 70                 //若数字前边有两个运算符,第一个是为了与前边的数相连,第二个是为了表示这个数的正负,则跳出循环,执行后面的语句
 71                 //比如: 5+(7+-5*+10),搜索到5前边时,先搜索到"-",发现前边还有一个"+",此时temp中没有运算符,则继续执行,当搜索到"+"时,发现前边没有运算符了,就跳出循环
 72                 if((src.charAt(k) == ‘+‘ || src.charAt(k) == ‘-‘) && (src.charAt(k-1) != ‘+‘ || src.charAt(k-1) != ‘-‘ ))
 73                     break;
 74                 if(temp.charAt(0) == ‘+‘ || temp.charAt(0) == ‘-‘)
 75                     break;
 76
 77             }catch(Exception e){
 78 //                e.printStackTrace();    //不输出异常,满足题目输出要求
 79             }
 80
 81             temp.insert(0, src.charAt(k));    //每次都是从temp的开始位置插入内容,保证逆向搜索的内容能按照正常的顺序存入temp
 82             src.deleteCharAt(k);            //删除运算符前边的那个数字,若有正负号,也一并删除
 83         }
 84
 85         x = Integer.parseInt(temp.toString());    //将搜索到的此数存入x
 86         temp.delete(0, temp.length());            //将temp清空
 87
 88         for(k = k + 2; k < src.length() && check.contains(src.charAt(k) + ""); ){    //从运算符右边一个位置开始往后搜索,找到第二个操作数,加2是因为上边的循环语句在结束时自减了一次
 89
 90             if((src.charAt(k) == ‘+‘ || src.charAt(k) == ‘-‘) && (temp.length() != 0))
 91                 break;
 92
 93             temp.append(src.charAt(k));
 94             src.deleteCharAt(k);
 95         }
 96
 97         y = Integer.parseInt(temp.toString());
 98         temp.delete(0, temp.length());
 99
100         switch(op){
101             case ‘+‘:
102                 sum = x + y;
103                 src.deleteCharAt(k-1);        //删除运算符
104                 src.insert(k-1, sum + "");    //将结果存入src的操作符位置(此时操作符两边的数已经从src中删除,所以插入此位置相当于用结果代替子表达式,方便下一次运算)
105                 break;
106
107             case ‘-‘:
108                 sum = x - y;
109                 src.deleteCharAt(k-1);
110                 src.insert(k-1, sum + "");
111                 break;
112
113             case ‘*‘:
114                 sum = x * y;
115                 src.deleteCharAt(k-1);
116                 src.insert(k-1, sum + "");
117                 break;
118
119             case ‘/‘:
120                 sum = x / y;
121                 src.deleteCharAt(k-1);
122                 src.insert(k-1, sum + "");
123                 break;
124
125             default:
126                 break;
127         }
128     }
129 }
时间: 2024-10-26 18:31:13

蓝桥杯 算法训练 ALGO-156 表达式计算的相关文章

蓝桥杯——算法训练之乘积最大

问题描述 今年是国际数学联盟确定的"2000--世界数学年",又恰逢我国著名数学家华罗庚先生诞辰90周年.在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸得以参加.活动中,主持人给所有参加活动的选手出了这样一道题目: 设有一个长度为N的数字串,要求选手使用K个乘号将它分成K+1个部分,找出一种分法,使得这K+1个部分的乘积能够为最大. 同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子: 有一个数字串:312, 当N=3,K=1时

蓝桥杯-算法训练 前缀表达式

算法训练 前缀表达式 时间限制:1.0s   内存限制:512.0MB 问题描述 编写一个程序,以字符串方式输入一个前缀表达式,然后计算它的值.输入格式为:“运算符 对象1 对象2”,其中,运算符为“+”(加法).“-”(减法).“*”(乘法)或“/”(除法),运算对象为不超过10的整数,它们之间用一个空格隔开.要求:对于加.减.乘.除这四种运算,分别设计相应的函数来实现. 输入格式:输入只有一行,即一个前缀表达式字符串. 输出格式:输出相应的计算结果(如果是除法,直接采用c语言的“/”运算符,

蓝桥杯 算法训练 ALGO-124 数字三角形

算法训练 数字三角形 时间限制:1.0s   内存限制:256.0MB 问题描述 (图3.1-1)示出了一个数字三角形. 请编一个程序计算从顶至底的某处的一条路 径,使该路径所经过的数字的总和最大. ●每一步可沿左斜线向下或右斜线向下走: ●1<三角形行数≤100: ●三角形中的数字为整数0,1,-99: . (图3.1-1) 输入格式 文件中首先读到的是三角形的行数. 接下来描述整个三角形 输出格式 最大总和(整数) 样例输入 573 88 1 02 7 4 44 5 2 6 5 样例输出 3

蓝桥杯 算法训练 2的次幂表示

算法训练 2的次幂表示 时间限制:1.0s   内存限制:512.0MB 问题描述 任何一个正整数都可以用2进制表示,例如:137的2进制表示为10001001. 将这种2进制表示写成2的次幂的和的形式,令次幂高的排在前面,可得到如下表达式:137=2^7+2^3+2^0 现在约定幂次用括号来表示,即a^b表示为a(b) 此时,137可表示为:2(7)+2(3)+2(0) 进一步:7=2^2+2+2^0 (2^1用2表示) 3=2+2^0  所以最后137可表示为:2(2(2)+2+2(0))+

蓝桥杯 算法训练 最短路

算法训练 最短路 时间限制:1.0s   内存限制:256.0MB 问题描述 给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环).请你计算从1号点到其他点的最短路(顶点从1到n编号). 输入格式 第一行两个整数n, m. 接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边. 输出格式 共n-1行,第i行表示1号点到i+1号点的最短路. 样例输入 3 31 2 -12 3 -13 1 2 样例输出 -1-2 数据规模与约定 对于10%的数据,n = 2,

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

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

蓝桥杯 算法训练 ALGO-36 传纸条

算法训练 传纸条 时间限制:1.0s   内存限制:512.0MB 问题描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的是,他们可以通过传纸条来进行交流.纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n).从小渊传到小轩的纸条只可以向下或者向右传递,从小轩传给小渊的纸条只可以向上或者向左传递. 在

蓝桥杯 算法训练 ALGO-147 4-3水仙花数

算法训练 4-3水仙花数 时间限制:1.0s   内存限制:256.0MB 问题描述 打印所有100至999之间的水仙花数.所谓水仙花数是指满足其各位数字立方和为该数字本身的整数,例如 153=1^3+5^3+3^3. 样例输入 一个满足题目要求的输入范例.例:无 样例输出 153xxxxxx 题目解析: 这是一道简单的暴力破解的题目.只需分解出每个三位数的百位.十位和个位,然后计算其三次方是否等于该数即可. 示例代码: 1 public class Main { 2 public static

蓝桥杯 算法训练 ALGO-149 5-2求指数

算法训练 5-2求指数 时间限制:1.0s   内存限制:256.0MB 问题描述 已知n和m,打印n^1,n^2,...,n^m.要求用静态变量实现.n^m表示n的m次方.已知n和m,打印n^1,n^2,...,n^m.要求用静态变量实现.n^m表示n的m次方.(每行显示5个数,每个数宽为12,右对齐) 样例输入 一个满足题目要求的输入范例.例:3 8 样例输出 与上面的样例输入对应的输出.例: 数据规模和约定 输入数据中每一个数的范围. 例:n^m小于int 的表示范围. 题目解析: 这是一