题解 | #四则运算#

四则运算

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();
    }
  }
}
全部评论

相关推荐

美团 后端开发 总包n(15%是股票)
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务