华为机考——LISP 加减乘除语句解析并计算结果
同样是准备华为机考时做的一道题:
简单的 LISP 加减乘除语句解析并计算结果,四种运算符号为 add、sub、mul、div,分别为加减乘除。其中数字部分皆为整数。除法取整,除数为零输出 error。
例子:
(add 3 5 7) 结果为 15
(sub 1 9) 结果为 -8
(mul 0 9) 结果为 0
(div 8 3) 结果为 2
(div 8 0) 结果为 error
(add (sub (div 8 2) (mul 1 9)) 20) 结果为 15 #原题链接
确实正统的思路是用栈去实现啦,而且对特别复杂的公式而言效率会很高,但是不觉得只是一个简单的字符串处理没必要用那么复杂(主要是不想引java.util.Stack包,滑稽 )
废话就不多说了,主要实现思路是递归策略,每次递归都只计算最小的子串,例如:
(div (add (sub (div 8 2) (mul 1 9)) 20) (div 6 (add 1 1)))
=> div (add (sub (div 8 2) (mul 1 9)) 20) (div 6 (add 1 1))
=> (div (add (sub 4 9) 20) (div 6 2))
=> (div (add -5 20) 3)
=> (div 15 3)
=> 5
代码实现
package test;import java.math.BigDecimal;/*** 公式计算* * @author mona*/
public class Compute {public static void main(String[] args) {String s1 = "(add 3 5 7)";String s2 = "(sub 1 9 5)";String s3 = "(mul 2 9 1.5)";String s4 = "(div 20 2 3)";String s5 = "(div 8 0)";String s6 = "(add (sub (div 8 2) (mul 1 9)) 20)";String s7 = "div (add (sub (div 8 2) (mul 1 9)) 20) (div 6 (add 1 1))";System.out.println(getResult(s1));System.out.println(getResult(s2));System.out.println(getResult(s3));System.out.println(getResult(s4));System.out.println(getResult(s5));System.out.println(getResult(s6));System.out.println(getResult(s7));}/*** 计算方法(递归)* * @param s* 输入公式* @return 输出结果*/private static String getResult(String s) {try {// System.out.println("s => " + s);if (!s.startsWith("(")) {s = "(" + s + ")";// 兼容}String[] sa = s.split("\\(");for (int i = 0; i < sa.length; i++) {if (sa.length > 0) {// System.out.println("sa[" + i + "] => " + sa[i]);if (sa[i].indexOf(")") >= 0) {BigDecimal sa_r = null;String[] saa = null;String fun = "";if (sa[i].trim().startsWith("add")) {fun = "add";String sa_add = sa[i].trim().substring((sa[i].trim().indexOf(fun + " ") + 4), sa[i].trim().indexOf(")"));saa = sa_add.split(" ");sa_r = new BigDecimal(saa[0]);for (int j = 1; j < saa.length; j++) {sa_r = sa_r.add(new BigDecimal(sa_add.split(" ")[j]));}s = s.replace("(" + fun + " " + sa_add + ")", sa_r + "");} else if (sa[i].trim().startsWith("sub")) {fun = "sub";String sa_sub = sa[i].trim().substring((sa[i].trim().indexOf(fun + " ") + 4), sa[i].trim().indexOf(")"));saa = sa_sub.split(" ");sa_r = new BigDecimal(saa[0]);for (int j = 1; j < saa.length; j++) {sa_r = sa_r.subtract(new BigDecimal(sa_sub.split(" ")[j]));}s = s.replace("(" + fun + " " + sa_sub + ")", sa_r + "");} else if (sa[i].trim().startsWith("mul")) {fun = "mul";String sa_mul = sa[i].trim().substring((sa[i].trim().indexOf(fun + " ") + 4), sa[i].trim().indexOf(")"));saa = sa_mul.split(" ");sa_r = new BigDecimal(saa[0]);for (int j = 1; j < saa.length; j++) {sa_r = sa_r.multiply(new BigDecimal(sa_mul.split(" ")[j]));}s = s.replace("(" + fun + " " + sa_mul + ")", sa_r + "");// s = s.replace("(" + fun + " " + sa_mul + ")", sa_r.setScale(0, BigDecimal.ROUND_HALF_UP) + "");// 四舍五入} else if (sa[i].trim().startsWith("div")) {fun = "div";String sa_div = sa[i].trim().substring((sa[i].trim().indexOf(fun + " ") + 4),sa[i].trim().indexOf(")"));saa = sa_div.split(" ");sa_r = new BigDecimal(saa[0]);for (int j = 1; j < saa.length; j++) {if (new BigDecimal(sa_div.split(" ")[j]).equals(BigDecimal.ZERO)) {return "Error";// 除数不能为0} else {sa_r = sa_r.divide(new BigDecimal(sa_div.split(" ")[j]), BigDecimal.ROUND_HALF_UP);}}s = s.replace("(" + fun + " " + sa_div + ")", sa_r + "");}}}}if (s.indexOf("add") >= 0 || s.indexOf("sub") >= 0 || s.indexOf("mul") >= 0 || s.indexOf("div") >= 0) {return getResult(s);} else {return s;}} catch (Exception e) {return "Unknown Error";}}
}
当然了,不考虑特别复杂的计算的话,可以不用引BigDecimal包,我只是考虑到了一些特别麻烦的除法所以引入了而已。
之所以想用递归实现,不仅仅是因为觉得用栈麻烦,还为了方便异常字符处理,可能是我最近做前端太久了,潜意识总在想着异常输入的处理哈哈哈
解决问题的思路肯定不止一种,我只是提供了另一种解题思路而已,继续去做题了。
华为机考——LISP 加减乘除语句解析并计算结果相关推荐
- 2020-05-10 华为机考机试题目两题
考试注意 牛客网考试 摄像头打开 屏幕录制 手机微信扫码保持屏幕常亮 可使用自己的 IDE 第一题 简单的 LISP 加减乘除语句解析并计算结果,四种运算符号为 add.sub.mul.div,分别为 ...
- 「解析」牛客网-华为机考企业真题 1-20
又是一年春招时,有幸收到华为自动驾驶算法岗,之前刷题不多,在此汇总下牛客网的真题,主要采用Python编写,个人觉得语言只是实现工具而已,并不是很关键,Python简洁易懂,更加适合算法工程师快速验证 ...
- 「解析」牛客网-华为机考企业真题 41-60
又是一年春招时,有幸收到华为自动驾驶算法岗,之前刷题不多,在此汇总下牛客网的真题,主要采用Python编写,个人觉得语言只是实现工具而已,并不是很关键,Python简洁易懂,更加适合算法工程师快速验证 ...
- 「解析」牛客网-华为机考企业真题 81-108
又是一年春招时,有幸收到华为自动驾驶算法岗,之前刷题不多,在此汇总下牛客网的真题,主要采用Python编写,个人觉得语言只是实现工具而已,并不是很关键,Python简洁易懂,更加适合算法工程师快速验证 ...
- 「解析」牛客网-华为机考企业真题 21-40
又是一年春招时,有幸收到华为自动驾驶算法岗,之前刷题不多,在此汇总下牛客网的真题,主要采用Python编写,个人觉得语言只是实现工具而已,并不是很关键,Python简洁易懂,更加适合算法工程师快速验证 ...
- 华为机考HJ13句子逆序C语言弱智解法
华为机考HJ13句子逆序C语言弱智解法 句子逆序C语言低端解法,易于理解. 1.收数据老生常谈. 2.将句子全部逆序. 3.将单词正序. (这里有一个bug,最后一个词(原句子第一个词)总是收不到,所 ...
- 华为机考HJ7取近似值
华为机考HJ7取近似值 只有小数点后一位,所以扩大十倍,让小数点后的数都为0. 然后强制转换成整型,不会影响精度. 强制转换原数的数据类型,无论原数据是什么,都只保留整数部分. 将扩大后的数对10求余 ...
- 华为机考HJ2计算字符个数
华为机考HJ2计算字符个数 gets();每次收一行字符. getchar();每次收一个字符. 两个都存储后用第二个在第一个串中检索. 大小写的问题用大小写的ASCII码差值32解决. 暴力破解,没 ...
- 华为机考HJ1字符串最后一个单词的长度
华为机考HJ1字符串最后一个单词的长度C语言解法 统计的是字符串最后一个单词的长度. 而不是单词的内容,所以单词的内容并不重要. 只需要用空格来做标志位即可. getchar():每次只收一个字符. ...
最新文章
- windows下给定多个openNi的Uri,匹配与uri对应的Uvc RGB设备
- Samba 系列(九):将 CentOS 7 桌面系统加入到 Samba4 AD 域环境中
- 任意进制转换简单理解
- 关于虚函数的应用(10个例子)
- python访问数据库oracle_python连接oracle数据库
- 怎样增加混凝土粘聚性_如何改善中低强度等级混凝土粘聚性? 这篇文章一定要看...
- 【BZOJ5469】[FJOI2018]领导集团问题(动态规划,线段树合并)
- kuka程序备份_那智机器人系统备份步骤
- [深度学习]理解RNN, GRU, LSTM 网络
- 【转】linx 设备名字来由 sd sr sg st
- 计数 APP android,SharedPreferences初学~个人备忘录以及对进入APP的次数进行计数
- RAISR-master:google图像新压缩技术RAISR的测试代码调试记录(Python实现,没接触过python的小白,内含pip install解决方案)
- 真正的轻量级WebService框架——使用JAX-WS(JWS)发布WebService
- 知识图谱基础入门(二)
- Xshell4 注册码 ,Xftp4 注册码
- 更改计算机时间格式,修改电脑日期时间显示格式
- ENSP与本地网络互连
- Altium未连接的网络DRC检查不出的问题
- 微商最低成本引流,学会这招日引精准粉1000+
- delphi xe 10.3 firemonkey stringdrig 插入,删除,添加