赞
踩
提取字符串中的最长合法简单数学表达式,字符串长度最长的,并计算表达式的值。如果没有,则返回0。简单数学表达式只能包含以下内容:0-9数字,符号 +-*
字符串
表达式值
输入:
1-2abcd
输出:
-1
import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; public class Main { private static final String v = "0123456789+-*"; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String str = scanner.nextLine(); List<String> formulas = new ArrayList<>(); char[] chars = str.toCharArray(); // 提取可能的合法表达式 for (int i = 0; i < str.length(); i++) { char c = chars[i]; if (Character.isDigit(c)) { int start = i; while (i + 1 < chars.length && v.contains(chars[i + 1] + "")) { if (!Character.isDigit(chars[i]) && !Character.isDigit(chars[i + 1]) && chars[i + 1] != '-') { break; } i++; } if (!Character.isDigit(str.charAt(i))) { formulas.add(str.substring(start, i)); } else { formulas.add(str.substring(start, i + 1)); } } } // 按长度排序,找到最长的表达式 Collections.sort(formulas, (f1, f2) -> Integer.compare(f2.length(), f1.length())); if (formulas.size() > 0) { String res = calculateFormula(formulas.get(0)); System.out.println(res); } else { System.out.println(0); } } /** * 计算给定表达式的值 * @param formula 数学表达式字符串 * @return 表达式的计算结果 */ private static String calculateFormula(String formula) { char[] chars = formula.toCharArray(); StringBuilder builder = new StringBuilder(); for (int i = 0; i < chars.length; i++) { if (Character.isDigit(chars[i])) { builder.append(chars[i]); } else if (!Character.isDigit(chars[i]) && i != chars.length - 1) { builder.append(",").append(chars[i]).append(","); } } List<String> list = Stream.of(builder.toString().split(",")).collect(Collectors.toList()); // 处理每个数字,以应对例如:"0200"的情况,将其转化为:"200" for (int i = 0; i < list.size(); i++) { if (!list.get(i).equals("+") && !list.get(i).equals("*") && !list.get(i).equals("-")) { long num = Long.parseLong(list.get(i)); list.set(i, num + ""); } } if (list.size() == 1) { return list.get(0); } // 先计算乘法,再计算加减 for (int i = 0; i < list.size(); i++) { if (list.get(i).equals("*")) { calculate(list, i, "*"); i = 0; } } for (int i = 0; i < list.size(); i++) { if (list.get(i).equals("+")) { calculate(list, i, "+"); i = 0; } if (i < list.size() && list.get(i).equals("-")) { calculate(list, i, "-"); i = 0; } } return list.get(0); } private static void calculate(List<String> list, int i, String op) { long a = Long.parseLong(list.get(i - 1)); long b = Long.parseLong(list.get(i + 1)); long res = 0L; switch (op) { case "*": res = a * b; break; case "+": res = a + b; break; case "-": res = a - b; break; } list.set(i, res + ""); list.remove(i-1); list.remove(i); } }
尽管参考,但建议各位不要全数抄写参考的代码,因为里面的问题还是不少的,需要注意判别,例如:
// 判断条件:操作符不能连续出现
// 错误❌
if (!Character.isDigit(cur) && !Character.isDigit(chars[i + 1])) {
break;
}
// 正确✔
if (!Character.isDigit(chars[i]) && !Character.isDigit(chars[i + 1])) {
break;
}
regex = "[0-9+\\-*]+"
?因为如果使用正则表达式regex,将输入的字符串 str
通过 str = str.replaceAll(regex, "")
,会删去字符串中非0-9数字以及符号 ±*外的其他字符,但是这也会导致一些问题,例如:当我们输入:1+2+3abc45+1
时,如果采用正则表达式的方式,会导致获取的最长表达式为:1+2+345+1
,但是这明显是不对的,而通过判断各个字符是否符合标准的方式则得到的最长表达式为:1+2+3
。
在代码中有如此一段:
if (!Character.isDigit(str.charAt(i))) {
formulas.add(str.substring(start, i));
} else {
formulas.add(str.substring(start, i + 1));
}
这是因为在判断可能存在的字符串时使用的条件是:没有连续的操作符
但是在判断例如:1+2+3+
的表达式时,就没办法正确处理最后一个字符,最后保存的表达式可能就是 1+2+3+
,这明显不正确,因此设置 if
条件来处理可能的表达式。
calculateFormula
中将 String
类型的数值转换为 Long
类型?具体代码:
for (int i = 0; i < list.size(); i++) {
if (!list.get(i).equals("+") && !list.get(i).equals("*") && !list.get(i).equals("-")) {
long num = Long.parseLong(list.get(i));
list.set(i, num + "");
}
}
这是因为在测试用例中有输入类似: 0200
的情况,这样输出的结果为:0200
,不符合要求,故进行处理。
注意:在遇到 0200 + 1
的情况无论有无这段代码都不会出现 0201
的情况。
这是因为测试用例本身就有问题,在测试用例中有如此两个用例:
用例编号: test_16
用例一: -02
预期输出: 0
用例编号: test_15
用例二: 12345
预期输出: 12345
这两个用例之间存在逻辑矛盾,对于 -02
,如果理想算法认为负数合法的话,预期输出应为: -2
,但是并不是,这说明在判断表达式是否合法的条件上有一条,即:操作符的两侧必有数字以构成表达式,否则非法;同时,也说明了不能将数值单独作为表达式,否则的话预期输出就应当为:2
。但是,很明显的是,结合用例二,我们可以知道单独的数值也能作为表达式,如此一来,两个用例之间自相矛盾,无法同时处理。
题目编号 | 结果 | 内存 | 时间 | 语言 | 代码长度 |
---|---|---|---|---|---|
3005 | 答案错误 AC:88.9% | 36904 KiB | 2248 ms | Java/Edit | 4619 bytes |
侵权必删声明
本资料部分内容来源于互联网及公开渠道,仅供学习和交流使用,版权归原作者所有。若涉及版权问题,敬请原作者联系我,我将立即处理或删除相关内容。感谢您的理解与支持。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。