Java 骰子公式计算器
我编写了两个函数,它们接受格式化字符串,定义骰子的数量和大小,抛出它们,并添加它们的值。 例如:3d8意味着掷3个骰子,每个骰子有8个边,并加上它们的值。这些值始终为正值,因此每次对3d8运行此函数时,我都可以得到3到24之间的值Java 骰子公式计算器,java,regex,Java,Regex,我编写了两个函数,它们接受格式化字符串,定义骰子的数量和大小,抛出它们,并添加它们的值。 例如:3d8意味着掷3个骰子,每个骰子有8个边,并加上它们的值。这些值始终为正值,因此每次对3d8运行此函数时,我都可以得到3到24之间的值 public int calcDice(String diceFormula){ String[] divided = diceFormula.split("d"); int cant = Integer.parseInt(di
public int calcDice(String diceFormula){
String[] divided = diceFormula.split("d");
int cant = Integer.parseInt(divided[0]);
int dice = Integer.parseInt(divided[1]);
int result = 0;
for (int i = 0; i < cant; i++) {
result += throwDice(dice);
}
return result;
}
private int throwDice(int diceSize) {
diceSize = diceSize < 0 ? dice * -1 : diceSize;
Random r = new Random();
return r.nextInt((diceSize - 1) + 1) + 1;
}
public int calcDice(字符串计算公式){
String[]divided=diceFormula.split(“d”);
int-cant=Integer.parseInt(除以[0]);
int dice=Integer.parseInt(除以[1]);
int结果=0;
对于(int i=0;i
我现在需要的是,能够使用这些值生成数学函数,这样我就可以输入一个将要计算的数学函数。我需要尊重决议顺序
例如,((3d8)+1)x(2d4)x 3
其中一个想法是先获取字符串并处理值,然后替换javascript计算器来计算结果,但我不确定如何“选择”值。
(可能是正则表达式?我解决这个问题的方法是实现一个能够解析数学表达式的
调车场
函数
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ShuttingYard {
private final Map<String, Integer> operators = new HashMap<>();
public ShuttingYard(){
operators.put("-", 0);
operators.put("+", 0);
operators.put("/", 1);
operators.put("*", 1);
operators.put("^", 2);
}
public double doTheShuntingYard(String expression)throws IllegalArgumentException, NumberFormatException, ArithmeticException{
if(expression == null || expression.trim().length() == 0)
throw new IllegalArgumentException("Empty expression or null");
expression = expression.replaceAll("\\s+","");
expression = expression.replace("(-", "(0-");
if (expression.startsWith("-")){
expression = "0" + expression;
}
Pattern pattern = Pattern.compile("((([0-9]*[.])?[0-9]+)|([\\+\\-\\*\\/\\(\\)\\^]))");
Matcher matcher = pattern.matcher(expression);
int counter = 0;
List<String> tokens = new ArrayList<>();
while(matcher.find()){
if(matcher.start() != counter){
throw new IllegalArgumentException("Invalid Expression:" + expression + ". Error between " + counter+ " end " + matcher.start());
}
tokens.add(matcher.group().trim());
counter += tokens.get(tokens.size() - 1 ).length();
}
if(counter != expression.length()){
throw new IllegalArgumentException("Invalid end of expression");
}
Stack<String> stack = new Stack<>();
List<String> output = new ArrayList<>();
for(String token : tokens){
if(operators.containsKey(token)){
while(!stack.empty() &&
operators.containsKey(stack.peek())&&
((operators.get(token) <= operators.get(stack.peek()) && !token.equals("^"))||
(operators.get(token) < operators.get(stack.peek()) && token.equals("^")))){
output.add(stack.pop());
}
stack.push(token);
}
else if(token.equals("(")){
stack.push(token);
}
else if(token.equals(")")){
while(!stack.empty()){
if(!stack.peek().equals("(")){
output.add(stack.pop());
}
else{
break;
}
}
if(!stack.empty()){
stack.pop();
}
}
else{
output.add(token);
}
}
while(!stack.empty()){
output.add(stack.pop());
}
Stack<Double> doubles = new Stack<>();
for(String token : output){
if(!operators.containsKey(token) && token.matches("([0-9]*[.])?[0-9]+")){
try{
doubles.push(Double.parseDouble(token));
}
catch(NumberFormatException n){
throw n;
}
}
else{
if(doubles.size() > 1){
double op1 = doubles.pop();
double op2 = doubles.pop();
switch (token) {
case "+":
doubles.push(op2 + op1);
break;
case "-":
doubles.push(op2 - op1);
break;
case "*":
doubles.push(op2 * op1);
break;
case "/":
if(op1 == 0){
throw new ArithmeticException("Division by 0");
}
doubles.push(Math.floor(op2 / op1));
break;
case "^":
doubles.push(Math.pow(op2, op1));
break;
default:
throw new IllegalArgumentException(token + " is not an operator or is not handled");
}
}
}
}
if(doubles.empty() || doubles.size() > 1){
throw new IllegalArgumentException("Invalid expression, could not find a result. An operator seems to be absent");
}
return doubles.peek();
}
}
我解决这个问题的方法是实现一个能够解析数学表达式的
调车场
函数
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ShuttingYard {
private final Map<String, Integer> operators = new HashMap<>();
public ShuttingYard(){
operators.put("-", 0);
operators.put("+", 0);
operators.put("/", 1);
operators.put("*", 1);
operators.put("^", 2);
}
public double doTheShuntingYard(String expression)throws IllegalArgumentException, NumberFormatException, ArithmeticException{
if(expression == null || expression.trim().length() == 0)
throw new IllegalArgumentException("Empty expression or null");
expression = expression.replaceAll("\\s+","");
expression = expression.replace("(-", "(0-");
if (expression.startsWith("-")){
expression = "0" + expression;
}
Pattern pattern = Pattern.compile("((([0-9]*[.])?[0-9]+)|([\\+\\-\\*\\/\\(\\)\\^]))");
Matcher matcher = pattern.matcher(expression);
int counter = 0;
List<String> tokens = new ArrayList<>();
while(matcher.find()){
if(matcher.start() != counter){
throw new IllegalArgumentException("Invalid Expression:" + expression + ". Error between " + counter+ " end " + matcher.start());
}
tokens.add(matcher.group().trim());
counter += tokens.get(tokens.size() - 1 ).length();
}
if(counter != expression.length()){
throw new IllegalArgumentException("Invalid end of expression");
}
Stack<String> stack = new Stack<>();
List<String> output = new ArrayList<>();
for(String token : tokens){
if(operators.containsKey(token)){
while(!stack.empty() &&
operators.containsKey(stack.peek())&&
((operators.get(token) <= operators.get(stack.peek()) && !token.equals("^"))||
(operators.get(token) < operators.get(stack.peek()) && token.equals("^")))){
output.add(stack.pop());
}
stack.push(token);
}
else if(token.equals("(")){
stack.push(token);
}
else if(token.equals(")")){
while(!stack.empty()){
if(!stack.peek().equals("(")){
output.add(stack.pop());
}
else{
break;
}
}
if(!stack.empty()){
stack.pop();
}
}
else{
output.add(token);
}
}
while(!stack.empty()){
output.add(stack.pop());
}
Stack<Double> doubles = new Stack<>();
for(String token : output){
if(!operators.containsKey(token) && token.matches("([0-9]*[.])?[0-9]+")){
try{
doubles.push(Double.parseDouble(token));
}
catch(NumberFormatException n){
throw n;
}
}
else{
if(doubles.size() > 1){
double op1 = doubles.pop();
double op2 = doubles.pop();
switch (token) {
case "+":
doubles.push(op2 + op1);
break;
case "-":
doubles.push(op2 - op1);
break;
case "*":
doubles.push(op2 * op1);
break;
case "/":
if(op1 == 0){
throw new ArithmeticException("Division by 0");
}
doubles.push(Math.floor(op2 / op1));
break;
case "^":
doubles.push(Math.pow(op2, op1));
break;
default:
throw new IllegalArgumentException(token + " is not an operator or is not handled");
}
}
}
}
if(doubles.empty() || doubles.size() > 1){
throw new IllegalArgumentException("Invalid expression, could not find a result. An operator seems to be absent");
}
return doubles.peek();
}
}
一种可能的解决方案是在字符串中替换
throwDice
部分,然后在此处使用答案:感谢您的评论。我也想到了这一点,但问题是,计算内部运算时必须去掉小数。因此,在这个数学世界中,10/3等于3,而不是3.333。一个可能的解决方案是在字符串中替换throwDice
部分,然后在这里使用答案:谢谢你的评论。我也想到了这一点,但问题是,计算内部运算时必须去掉小数。所以在这个数学世界里,10/3等于3,而不是3.333