gpt4 book ai didi

java - 骰子公式评估器

转载 作者:太空宇宙 更新时间:2023-11-04 09:06:54 25 4
gpt4 key购买 nike

我编写了几个函数,它们采用格式化字符串,定义骰子的数量和骰子的大小,抛出它们,并将它们的值相加。例如:3d8 表示掷 3 个骰子,每个骰子有 8 个面,然后将它们的值相加。这些值始终为正数,因此每次我为 3d8 运行此函数时,我都可以获得 3 到 24 之间的值。

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

我现在需要的是能够使用这些值创建数学函数,这样我就可以输入要计算的数学函数。我需要尊重决议顺序例如。 ((3d8)+1) x (2d4) x 3

其中一个想法是获取字符串并首先处理值,然后替换 javascript 求值器来找出结果,但我不确定如何“选择”这些值。(也许是正则表达式?)

最佳答案

为了解决这个问题,我所做的就是实现一个能够解析数学表达式的 ShuntingYard 函数

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 操作后调用此函数

public class DiceThrower{

private ShuttingYard shuttingYard;

public DiceThrower(){
this.shuttingYard = new ShuttingYard();
}

public void throwDiceAction(View view){

TextView result = findViewById(R.id.diceResult);
try{
String original = ((EditText)findViewById(R.id.formula)).getText().toString();
Pattern pattern = Pattern.compile("([0-9]{1,999})d([0-9]{1,999})");
Matcher matcher = pattern.matcher(original);
while(matcher.find()){
original = matcher.replaceFirst(Integer.toString(calcDice(matcher.group(0))));
matcher = pattern.matcher(original);
}
result.setText(evaluateExpression(original).split("\\.")[0]);
}catch(ArithmeticException e){
result.setText("This doesn't seem to be a valid mathematical expression");
}


}


public String evaluateExpression(String expression){
expression = expression.replaceAll("\\)\\(", ")*(");
expression = expression.replaceAll("x", "*");
return Double.toString(this.shuttingYard.doTheShuntingYard(expression));
}

public int calcDice(String formula){
String[] divided = formula.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 dice) {
dice = dice < 0 ? dice * -1 : dice;
Random r = new Random();
return r.nextInt((dice - 1) + 1) + 1;
}

}

关于java - 骰子公式评估器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60133795/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com