Cal.java:
package caculator_core;
import java.util.HashSet;
import java.util.Random;
import java.util.Scanner;
public class Calc {
public static void main(String[] args) {
System.out.println("-------输入0选择默认配置,输入1选择自定义配置-------");
Scanner scanner = new Scanner(System.in);
CalCore calCore = new CalCore();
int number = scanner.nextInt();
switch (number) {
case 0:
calCore =new CalCore();
break;
case 1:
System.out.println("-------请输入运算符总数------");
int numberTotal = scanner.nextInt();
System.out.println("-------请输入运算式个数------");
int formulaTotal = scanner.nextInt();
System.out.println("-------请输入最大运算数字------");
int numberRange = scanner.nextInt();
System.out.println("-------请输入运算结果最大值------");
int maxResult = scanner.nextInt();
System.out.println("-------是否包含乘除法------");
boolean includeMulAndDiv = false;
if(scanner.next().equals("是")) {
includeMulAndDiv = true;
}else {
includeMulAndDiv = false;
}
System.out.println("-------是否包含负数------");
boolean includeNegNum = false;
if(scanner.next().equals("是")) {
includeNegNum = true;
}else {
includeNegNum = false;
}
calCore = new CalCore(numberTotal,formulaTotal,numberRange,maxResult,includeMulAndDiv,includeNegNum);
default:
break;
}
HashSet<String> formulas = calCore.generateFormulas();
double [] arr = calCore.generateAnswers(formulas);
System.out.println(calCore.outputFormulas(formulas));
System.out.println(calCore.outputAnswers(arr));
}
}
CalCore.java:
package caculator_core;
import java.io.File;
import java.io.FileWriter;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashSet;
import java.util.Random;
import java.util.Stack;
public class CalCore {
//运算符总数
private int numberTotal;
//运算式个数
private int formulaTotal;
//数字范围
private int numberRange;
//运算结果最大值
private int maxResult;
//是否包含乘除法
private boolean includeMulAndDiv;
//是否包含负数
private boolean includeNegNum;
public CalCore() {
this.numberTotal = 2;
this.formulaTotal = 10;
this.numberRange = 100;
this.maxResult = 100;
this.includeMulAndDiv =false;
this.includeNegNum = false;
}
public CalCore(int numberTotal,int formulaTotal,int numberRange,int maxResult,boolean includeMulAndDiv,boolean includeNegNum) {
this.numberTotal = numberTotal;
this.formulaTotal = formulaTotal;
this.numberRange = numberRange;
this.maxResult = maxResult;
this.includeMulAndDiv = includeMulAndDiv;
this.includeNegNum = includeNegNum;
}
//生成随机数
public double getRandomNumber() {
Random random = new Random();
if(this.includeNegNum) {
double d = (random.nextInt(this.numberRange)+1)*(random.nextDouble()>0.5?1.0:-1.0)*(random.nextDouble());
BigDecimal bg = new BigDecimal(d).setScale(2, RoundingMode.UP);
return bg.doubleValue();
}else {
double d =(random.nextInt(this.numberRange)+1)*(random.nextDouble());
BigDecimal bg = new BigDecimal(d).setScale(2, RoundingMode.UP);
return bg.doubleValue();
}
}
//生成随机运算符
public String getRandomOperator() {
Random random = new Random();
String [] opreations = {"+","-","*","/"};
return opreations[random.nextInt((this.includeMulAndDiv == true)?4:2)];
}
//生成算式
public String generateFormula() {
String formula ="";
for(int i=0;i<this.numberTotal;i++) {
if(i>=this.numberTotal-1) {
formula += isNegNum(this.getRandomNumber());
continue;
}
formula += isNegNum(this.getRandomNumber())+" "+this.getRandomOperator() +" ";
}
return formula;
}
//如果负数就加括号
private String isNegNum(double randomNumber) {
if(randomNumber<0) {
return "("+randomNumber +")";
}
return ""+randomNumber;
}
//生成算式集合
public HashSet<String> generateFormulas(){
HashSet<String> set = new HashSet<String>();
while(set.size()<=this.formulaTotal) {
String formula = this.generateFormula();
if(this.maxResult>= getAnswer(formula)) {
set.add(formula);
}
}
return set;
}
//生成答案
public double[] generateAnswers(HashSet<String> set) {
double [] arr = new double[set.size()];
int i=0;
for(String str:set) {
arr[i++] = getAnswer(str);
}
return arr;
}
//打印算式
public String outputFormulas(HashSet<String> set) {
File file = new File("result.txt");
try {
FileWriter fw = new FileWriter(file);
for(String str:set) {
System.out.println(str);
fw.write(str+" ");
}
fw.close();
} catch (Exception e) {
System.out.println("Error"+e.getMessage());
System.exit(0);
}
return file.getAbsolutePath();
}
//打印答案
public String outputAnswers(double[]arr) {
File file = new File("answer.txt");
try {
FileWriter fw = new FileWriter(file);
for(int i=0;i<arr.length;i++) {
fw.write(arr[i]+" ");
}
fw.close();
} catch (Exception e) {
System.out.println("Error"+e.getMessage());
System.exit(0);
}
return file.getAbsolutePath();
}
public Double getAnswer(String formula) {
int length=0;
String [] formulaArr = formula.split(" ");
String operators = "+-*/";
Stack<Double> opNumbers = new Stack<Double>();
Stack<String> opOperators = new Stack<String>();
opOperators.add("#");//字符栈存个#,防止栈空
while(length<formulaArr.length) {
String op = formulaArr[length++];
//如果是运算符,判断优先级
//indexof方法,判断字符串第一次出现的位置,找不到为-1
if(operators.indexOf(op) >-1) {
String sign = opOperators.peek();//顶部出栈
int priority = compare(op,sign);//比较优先级
if(priority>=0) {//如果要入栈的运算符优先级高或相等,出栈两个数字,和之前的运算符计算后数字和字符分别入栈
opNumbers.add(compute(opOperators,opNumbers));
opOperators.add(op);
}else {//入栈运算符优先级低,直接入栈
opOperators.add(op);
}
continue;
}
//若是数字,则入栈
opNumbers.add(Double.parseDouble(op.replace("(", "").replace(")", "")));//将括号忽略掉
}
while (opOperators.peek()!="#") {
opNumbers.add(compute(opOperators, opNumbers));
}
return opNumbers.pop();
}
private Double compute(Stack<String> opOperators, Stack<Double> opNumbers) {
double num2 = opNumbers.pop();
double num1 = opNumbers.pop();
String _op = opOperators.pop();
double result =0.0;
switch(_op) {
case "+":
result=num1+num2;
break;
case "-":
result =num1-num2;
break;
case "*":
result =num1*num2;
break;
case "/":
result =num1/num2;
break;
}
BigDecimal bg = new BigDecimal(result).setScale(2, RoundingMode.UP);
result = bg.doubleValue();
return result;
}
private int compare(String operator1, String operator2) {
int res=0;
switch(operator1) {
case "+":
case "-":
if(operator2.equals("+")||operator2.equals("-")||operator2.equals("*")||operator2.equals("/")) {
res=1;
}else {
res=-1;
}
break;
case "*":
case "/":
if(operator2.equals("*")||operator2.equals("/")) {
res=1;
}else {
res=-1;
}
break;
}
return res;
}
}