这是刚出来找工作的时候被问到的面试题,当时面试官问我能不能现场写一个或者谈谈实现的思路,我刚出来的时候比较菜,所以没有回答上来...
今天突然想起这道面试题,最近也比较闲,所以就打算做一下。
效果图:
提示:表达式完整性我没有做验证,如少括号之类的...
实现的代码如下:
package cn.mlb.test;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String content = "";
String regex = "[0-9\\.+-/*()= ]+"; // 只能输入数字,()+-*/
while (true) {
System.out.println("请输入要计算字符串:");
// 读取字符串型输入
content = scanner.nextLine();
if ("end".equals(content)) { // 输入end结束
break;
} else if (!content.matches(regex)) {
System.out.println("输入的字符串不合法");
continue;
}
content = content.replaceAll(" ", ""); // 去除空格
test test = new test();
double calculator = test.calculator(content);
System.out.println("计算结果:" + calculator);
}
System.out.println("结束!!!");
}
/**
* 字符串计算
* @param expression
* @return
*/
public double calculator(String expression) {
if (expression == null || "".equals(expression)) {
return 0.0;
}
String exp = ""; // 去括号后的表达式
// 是否有括号
if (expression.contains("(") && expression.contains(")")) {
int starIndex = expression.indexOf("("); // 第一次出现括号的下标
if (starIndex > 0) {
exp = expression.substring(0, starIndex);
}
expression = expression.substring(starIndex + 1);
int num = 0; // 括号里还有括号的次数
for (int i = 0; i < expression.length(); i++) {
if ("(".equals(expression.charAt(i) + "")) {
num++;
}else if (")".equals(expression.charAt(i) + "") && num == 0) { // 结束括号
double value = calculator(expression.substring(0, i));
exp += value;
if (i + 1 < expression.length()) {
expression = expression.substring(i + 1);
starIndex = expression.indexOf("(");
if (starIndex != -1) { // 后面表达式存在括号
if (starIndex > 0) {
exp += expression.substring(0, starIndex);
}
expression = expression.substring(starIndex + 1);
i = -1;
}else { // 后面表达式没有括号
exp += expression;
break;
}
}
}else if (")".equals(expression.charAt(i) + "")) {
num--;
}
}
}else { // 没有括号
exp = expression;
}
// 表达式拆分到集合
List<String> list = new ArrayList<>();
String chars = "";
for (int i = 0; i < exp.length(); i++) {
chars = exp.charAt(i) + "";
if ("-".equals(chars) || "+".equals(chars) || "*".equals(chars) || "/".equals(chars)) {
if ("-".equals(chars) && list.size() == 0 && i == 0) {
list.add("0");
}else if (i != 0) {
list.add(exp.substring(0, i));
}
list.add(chars);
exp = exp.substring(i + 1);
i = -1;
}else if (i + 1 >= exp.length()) {
list.add(exp);
break;
}
}
// 计算表达式(先乘除后加减)
double results = 0.0;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < list.size(); j++) {
if (i == 0) {
if ("*".equals(list.get(j))) {
results = Double.parseDouble(list.get(j-1)) * Double.parseDouble(list.get(j+1));
}else if ("/".equals(list.get(j))) {
results = Double.parseDouble(list.get(j-1)) / Double.parseDouble(list.get(j+1));
}
if ("*".equals(list.get(j)) || "/".equals(list.get(j))) {
list.remove(j + 1);
list.remove(j);
list.remove(j - 1);
list.add(j - 1, results + "");
j--;
}
}else {
if ("+".equals(list.get(j))) {
results = Double.parseDouble(list.get(j-1)) + Double.parseDouble(list.get(j+1));
}else if ("-".equals(list.get(j))) {
results = Double.parseDouble(list.get(j-1)) - Double.parseDouble(list.get(j+1));
}
if ("+".equals(list.get(j)) || "-".equals(list.get(j))) {
list.remove(j + 1);
list.remove(j);
list.remove(j - 1);
list.add(j - 1, results + "");
j--;
}
}
}
}
// 结果保留两位小时
results = (double) Math.round(results * 100) / 100;
return results;
}
}