题解 | #四则运算#
四则运算
http://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e
- 分三步。先去括号、再计算乘除、再计算加减
- 去括号时,注意计算完有
+-
连体的情况,需要使用replaceAll
替换了。最后一个左括号和第一个右括号进行匹配 - 计算复杂表达式时,如果首位为
-
则补0。while
中-
的判断用了substring(1)
是为了避免计算结果为负数时的死循环 - 有乘除时,先依次计算乘除。注意边界,乘除后面可能跟一个负数,即
2*-3+4
- 计算乘除分割数字时,注意
3*-2
的情况
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.Scanner;
/**
* class com.sloera.nowcoder
* user sloera
* date 2022/2/21
*/
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
final String s = in.nextLine();
// String s = "3+2*{1+2*[-4/(8-6)+7]}";
// String s = "3*5+8-0*3-6+0+0";
// String s = "5-3+9*6*(6-10-2)";
// String s = "3+2*{1+2*[-4/(8-6)+7]}";
// canculateByEval(s);
canculate1(s);
}
private static void canculate1(String source) {
source = source.replaceAll("\\[", "(").replaceAll("\\]", ")").replaceAll("\\{", "(").replaceAll("\\}", ")");
while (source.contains("(")) {
source = calculateBrace(source);
}
final String s = calculateComplex(source);
System.out.println(s);
}
/**
* 计算最内括号的内容
*
* @return java.lang.String
* @date 2022/2/23
*/
private static String calculateBrace(String source) {
if (source.contains("(")) {
int count = 0;
int left = 0;
int right = 0;
for (int i = 0; i < source.length(); i++) {
if (source.charAt(i) == '(') {
left = i;
count++;
}
if (source.charAt(i) == ')') {
// if (count == 1) {
right = i;
break;
// }
// count--;
}
}
final String substring = source.substring(left + 1, right);
String result = calculateComplex(substring);
return source.replace("(" + substring + ")", result).replaceAll("\\+-", "-").replaceAll("-\\+", "-").replaceAll("--", "+");
}
return null;
}
/**
* 计算无括号的表达式
*
* @return int
* @date 2022/2/23
*/
private static String calculateComplex(String substring) {
if (substring.charAt(0) == '-') {
substring = "0" + substring;
}
while (substring.contains("+") || substring.substring(1).contains("-") || substring.contains("*") || substring.contains("/")) {
int i = substring.indexOf("*");
if (i == -1) {
i = substring.indexOf("/");
}
if (i != -1) {
int left = 0;
int right = substring.length();
for (int j = i - 1; j > 0; j--) {
if (substring.charAt(j) != '+' && substring.charAt(j) != '-') {
continue;
} else {
left = j;
break;
}
}
for (int j = i + 1; j < substring.length(); j++) {
if ((substring.charAt(j) != '+' && substring.charAt(j) != '-')) {
continue;
} else if (substring.charAt(j) == '-' && (substring.charAt(j - 1) == '*' || substring.charAt(j - 1) == '/')) {
j++;
while (j < substring.length() && substring.charAt(j) != '+' && substring.charAt(j) != '-') {
j++;
}
right = j;
break;
} else {
right = j;
break;
}
}
final String multiString = substring.substring(left == 0 ? left : left + 1, right);
substring = substring.replace(multiString, calculateMulti(multiString)).replaceAll("\\+-", "-").replaceAll("-\\+", "-").replaceAll("--", "+");
continue;
}
substring = calculateAdd(substring);
}
return substring;
}
private static String calculateAdd(String multiString) {
final String[] number = multiString.split("\\+|-");
final String[] operator = multiString.split("\\d+");
int result = Integer.parseInt(number[0]);
for (int i = 1; i < operator.length; i++) {
if (operator[i].equals("+")) {
result = result + Integer.parseInt(number[i]);
}
if (operator[i].equals("-")) {
result = result - Integer.parseInt(number[i]);
}
}
return String.valueOf(result);
}
private static String calculateMulti(String multiString) {
final String[] number = multiString.split("\\*|/");
final String[] operator = multiString.split("[\\d-]+");
int result = Integer.parseInt(number[0]);
for (int i = 1; i < operator.length; i++) {
if (operator[i].equals("*")) {
result = result * Integer.parseInt(number[i]);
}
if (operator[i].equals("/")) {
result = result / Integer.parseInt(number[i]);
}
}
return String.valueOf(result);
}
/**
* 通过eval
*
* @return void
* @date 2022/2/21
*/
private static void canculateByEval(String source) {
final ScriptEngine js = new ScriptEngineManager().getEngineByName("js");
try {
System.out.println(js.eval(source.replaceAll("\\[", "(").replaceAll("\\]", ")").replaceAll("\\{", "(").replaceAll("\\}", ")")));
} catch (ScriptException e) {
e.printStackTrace();
}
}
}