eclipse 如何在Java中正确使用parseInt?

zte4gxcn  于 9个月前  发布在  Eclipse
关注(0)|答案(3)|浏览(107)

我在计算机科学课上做一个项目,我的老师想要一个计算器,它可以把一个方程作为一个字符串来接受,例如。

5 + 5

(而不是通过每个变量)。
我的问题是如何正确的parseInt?它在数据到达操作员之前收集所有数据(int s)。我如何告诉它收集数据过去的运营商?
我试着遍历字符串本身,直到它找到一个操作符。根据使用的运算符,它会通过我的第二个类进行相应的计算。但它只能收集操作员之前的所有内容。我试过将字符串放入数组中并反向运行for循环,但似乎从未奏效。

lfapxunr

lfapxunr1#

如果你正在执行算术,你可能应该使用floatdouble而不是int
下面是一个解析简单算术表达式的基本示例。

public class Calculate {
    public static void main(String[] args) {
        String expression = "5 + 5";
        System.out.printf("%s = %.2f%n", expression, calculate(expression));

        try {
            calculate("33 + 5 * 2");
        } catch (IllegalArgumentException e) {
            System.out.println(e.getMessage());
        }

        try {
            calculate("33 % 2");
        } catch (IllegalArgumentException e) {
            System.out.println(e.getMessage());
        }
    }

    public static double calculate(String input) {
        String[] tokens = input.trim().split("\\s+");
        if (tokens.length != 3) {
            throw new IllegalArgumentException("Input must be in the form of: <operand_1> <operator> <operand_2>");
        }
        double operand1 = Double.parseDouble(tokens[0]);
        double operand2 = Double.parseDouble(tokens[2]);
        String operator = tokens[1];
        switch (operator) {
            case "+":
                return operand1 + operand2;
            case "-":
                return operand1 - operand2;
            case "*":
            case "x":
                return operand1 * operand2;
            case "/":
            case "÷":
                return operand1 / operand2;
            default:
                throw new IllegalArgumentException("Operator must be one of: +, -, *, /");
        }
    }
}

输出量:

5 + 5 = 10.00
Input must be in the form of: <operand_1> <operator> <operand_2>
Operator must be one of: +, -, *, /
qq24tv8q

qq24tv8q2#

将提供的等式拆分为特定的数组元素,我认为这也是一种方法。考虑到可以提供的不同类型的数学方程,这不一定是一件容易的事情。一个方程可能有带符号或无符号的数值,不同类型的括号(如**(){ }[ ]),Unicode字符(如PI(𝝅)),甚至可能是Unicode上标指数字符(如:、数学方程甚至可能是代数类型的,并且包含诸如“x”或“y”等字符。我相信你现在不需要处理这些方程,但你将来可能会想考虑一下。
要计算数学方程,需要将其分解为特定的元素,然后处理这些元素,并且应该在
BEDMAS**中进行处理以确保准确,即使它目前不是您当前用例的要求。
下面提供的方法将把一个数学字符串等式拆分成上面讨论的特定元素,并将其作为String[]数组返回。它看起来像很多代码,但实际上不是,因为它只是一个快速而简单的解析器。这是所有的评论,使它看起来很大,你可以稍后删除,如果你喜欢。请阅读代码中的评论:

/**
 * This method will parse a math equation string, even with various bracket
 * types or nested brackets and Unicode math operators or numerical
 * characters like PI (𝝅 - Unicode: \ud835\udf45)) into a String[] Array.
 * <p>
 * Signed and unsigned integer or floating point values can be within the
 * supplied mathematical equation. Numerical values with exponents will 
 * keep their respective exponent in the parsing. 
 * <p>
 * As an example, then following equation string: "(-3.786 + 2³) * (8² / 𝝅)" 
 * will be parsed as: [(, -3.786, +, 2³, ), *, 8², /, 𝝅]. 
 * <p>
 * In the above example, the superscript exponent characters ("⁰", "¹", "²", 
 * "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹") are respective Unicode characters
 * "\u2070", "\u00B9", "\u00B2", "\u00B3", "\u2074", "\u2075", "\u2076", 
 * "\u2077", "\u2078", "\u2079". 
 * <p>
 * The character 𝝅 is Unicode: \ud835\udf45.
 * <p>
 * Whitespaces are ignored during parsing and will not be contained within
 * the returned String[] Array as any kind of array element.<br>
 *
 * @param equation (String) The mathematical equation to parse into a String[] Array.<br>
 *
 * @return (String[] Array)
 */
public String[] splitSimpleEquation(String equation) {
    /* Remove all white-spacing from the supplied equation.
       We don't need them:              */
    equation = equation.replaceAll("\\s+", "");
    
    /* A List Interface of String to hold all the equation elements.
       This List is later converted to a String[] array and returned. 
       We use a List because we literally have no idea how big the 
       equation might be and because of this there is no real way to 
       know how large to initialize a String[] array. A List (or an 
       ArrayList) can grow dynamically and therefore, this wouldn't 
       be a problem:     */
    List<String> list = new ArrayList<>();
    
    // Will temporarily hold established numerical values within the equation:
    String number = ""; 
    
    /* Split the supplied equation into into a String[] array of individual
       characters so to establish proper parsing. The `equation.split("")` 
       could be used to do this but, this method WILL NOT handle two byte 
       Unicode caracters (like 𝝅) as required.        */
    String[] chr = equation.codePoints()
            .mapToObj(cp -> new String(Character.toChars(cp)))
            .toArray(size -> new String[size]);
    
    /* Iterate through the `chr` array and create the needed 
       elements to add to the List. `c` will hold the current
       string character being processed:         */
    for (String c : chr) {
        /* If the current string character is a numerical digit (0-9) or
           a decimal point (period) OR is the current string character 
           a minus character or any unicode minus character and is the 
           `number` variable empty (precursor to signed values) OR is the 
           current string character a Unicode superscript exponent character 
           and the `number` variable is NOT empty (precursor to (value to 
           the Power of) then, append the character to the contents contained 
           within the `number` variable:     */
        if (c.matches("[0-9]") || c.matches("[\\.]") || 
                (c.matches("[─➖\\-−−]") && number.isEmpty()) || 
                    (c.matches("[⁰¹²³⁴⁵⁶⁷⁸⁹]") && !number.isEmpty())) {
            number += c;
        }
        
        /* Otherwise, if the current string character is a numerical digit
           and the `number` variable is NOT empty then, add the value 
           currently held in `number` to the List, then empty `number` in
           preparation for a new value then, add the current string 
           numerical character value to the List:            */
        else if (!c.matches("\\d") && !number.isEmpty()) {
            list.add(number);   // Add current value of `number` to the List.
            number = "";        // Empty `number` variable in prep for new value.
            list.add(c);        // Add current string numerical value to List
        }
        
        /* Otherwise, just add the current string character to the List.
           This could be a open or close bracket, a unicode PI character, 
           etc.         */
        else {
            list.add(c);
        }
    }
    
    /* Once the `chr` array has finnished iterations and there
       is still a value contained within the `number` variable 
       then, add that value to the List:        */
    if (!number.isEmpty()) {
        list.add(number);
    }
    
    // Convert the List of String to a String[] array and return it;
    return list.toArray(new String[0]);
}

示例使用#1:

String[] equationElements = splitSimpleEquation("5 + 5 * 2");
System.out.println(Arrays.toString(equationElements));

输出显示:

[5, +, 5, *, 2]

示例使用#2:

String[] equationElements = splitSimpleEquation("(-3.786 + 2³)*(8²/𝝅)*x");
System.out.println(Arrays.toString(equationElements));

输出显示:

[(, -3.786, +, 2³, ), *, (, 8², /, 𝝅, ), *, x]
ohtdti5x

ohtdti5x3#

  • ".我的问题是如何正确解析Int?它在到达操作员之前收集所有数据(int)。我如何告诉它收集数据过去的运营商?..."*

使用 * Pattern * 和 * Matcher * 类来捕获值和运算符。
我用的是以下模式。
look-around Assert+-是运算符而不是符号。

(?:(?<![*/+-])[+-]|[*/])|[+-]?[^ */+-]+

这里有一个例子。

import static java.math.RoundingMode.HALF_UP;
String exp = "22/7";
Pattern p = Pattern.compile("(?:(?<![*/+-])[+-]|[*/])|[+-]?[^ */+-]+");
Matcher m = p.matcher(exp);
List<String> a = m.results().map(MatchResult::group).toList();
Iterator<String> it = a.iterator();
BigDecimal x = new BigDecimal(it.next()).setScale(32, HALF_UP);
while (it.hasNext()) {
    x = switch (it.next()) {
        case "*" -> x.multiply(new BigDecimal(it.next()));
        case "/" -> x.divide(new BigDecimal(it.next()), 32, HALF_UP);
        case "+" -> x.add(new BigDecimal(it.next()));
        case "-" -> x.subtract(new BigDecimal(it.next()));
        default -> x;
    };
}

输出

3.14285714285714285714285714285714

作为建议,研究 * Abstract Syntax Tree**数据结构 * 的主题。
本质上,它是一种解析技术,用于枚举和分类文本中的值。
这是一个常见的结构,用于 * interpreters *。
它非常强大,你可以计算复杂的方程。

相关问题