Java计算器(表达式可以有加,减,乘,除,括号)

这是刚出来找工作的时候被问到的面试题,当时面试官问我能不能现场写一个或者谈谈实现的思路,我刚出来的时候比较菜,所以没有回答上来...

今天突然想起这道面试题,最近也比较闲,所以就打算做一下。

效果图:

提示:表达式完整性我没有做验证,如少括号之类的...

实现的代码如下:

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;
	}

}

猜你喜欢

转载自blog.csdn.net/m_crayon/article/details/105109217