我怎么能解决这个错误,我的字符串方程convertin计算器? [英] How could I solve this error, with my string to equation convertin calculator?

查看:216
本文介绍了我怎么能解决这个错误,我的字符串方程convertin计算器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在写一个计算器code,解决了输入什么字符串给出。一切都很好,除非它得到负面的结果失败不好,因为两个操作获得相邻的括号:

I'm writing a calculator code that solves the input whats given in string. All is good, except when it gets a negative result in the parentheses it fails badly because two operations get next to each other:

1+2*(10-11) >> 1+2*(-1) >> 1+2*-1

那么,* - 是,它得到(无)在的BigDecimal 的构造。 我知道有什么问题,但我怎么能解决呢?

So where *- is, it gets "" (nothing) in the BigDecimal's constructor. I know what's the problem, but how can I solve it?

import java.math.BigDecimal;
import java.util.ArrayList;

public class DoMath {

    public static void main(String[] args) {

        // Test equation goes here.
        String number = "95.3+43.23*(10-11.1)";
        System.out.println(doMath(number));
    }

    public static BigDecimal doMath(String input) {

        StringBuilder builtInput = new StringBuilder(input);
        StringBuilder help = new StringBuilder();
        // Check if there are parenthesis in the equation.
        boolean noParenthesis = true;
        for (int i = 0; i < builtInput.length(); i++) {
            if (builtInput.charAt(i) == 40) {
                noParenthesis = false;
                break;
            }
        }

        if (noParenthesis) {    // If there are no parenthesis, calculate the equation!
            return calculateAndConvert(builtInput);

        } else {            // If there are parenthesis, breakdown to simple equations!
            int parenthesePair = 0;
            // Start extracting characters from the builtInput variable.
            for (int i = 0; i < builtInput.length(); i++) {
                // Start where we find a parentheses opener.
                if (builtInput.charAt(i) == 40) {
                    parenthesePair = 1;
                    builtInput.deleteCharAt(i);
                    for (int j = i; j < builtInput.length(); j++) {
                        // If we find another opener, add one to parenthesePair variable.
                        if (builtInput.charAt(j) == 40) {
                            parenthesePair++;
                        }
                        // If we find a closer, subtract one from the given variable.
                        if (builtInput.charAt(j) == 41) {
                            parenthesePair--;
                        }
                        // If we have found the matching pair, delete it and break the for loop.
                        if (parenthesePair == 0) {
                            builtInput.deleteCharAt(j);
                            builtInput.insert(j, doMath(help.toString()));
                            break;
                        }
                        help.append(builtInput.charAt(j));
                        builtInput.deleteCharAt(j);
                        j--;
                    }
                    break;
                }
            }
        }
        System.out.println(builtInput);
        return doMath(builtInput.toString());
    }

    public static BigDecimal calculateAndConvert(StringBuilder input) {

        ArrayList<BigDecimal> listOfNumbers = new ArrayList<BigDecimal>();
        StringBuilder numBay = new StringBuilder();
        StringBuilder operations = new StringBuilder();
        // If the first character is -, the first number is negative.
        boolean firstIsNegative = false;
        if (input.charAt(0) == 45) {
            firstIsNegative = true;
            input.deleteCharAt(0);
        }

        // Converting to numbers.
        while (input.length() != 0) {
            // If the character is a number or a dot, put it in the numBay variable and delete the char.
            if (input.charAt(0) >= 48 && input.charAt(0) <= 57 || input.charAt(0) == 46) {
                numBay.append(input.charAt(0));

                // If the character is not a number, put it in the operations variable
                // and save the number in the list (not operator characters are filtered)
            } else {
                listOfNumbers.add(new BigDecimal(numBay.toString()));
                numBay.setLength(0);
                operations.append(input.charAt(0));
            }
            // Delete the character.
            input.deleteCharAt(0);
        }
        listOfNumbers.add(new BigDecimal(numBay.toString()));

        // Setting first number to negative if it's needed.
        if (firstIsNegative) {
            listOfNumbers.set(0, listOfNumbers.get(0).negate());
        }

        // Calculate the result from the list and operations and return it.
        return calculate(listOfNumbers, operations);
    }

    public static BigDecimal calculate(ArrayList<BigDecimal> list, StringBuilder ops) {

        BigDecimal momentaryResult;
        // Check for a multiply operation - if there is one, solve it.
        for (int i = 0; i < ops.length(); i++) {
            if (ops.charAt(i) == 42) {
                momentaryResult = list.get(i).multiply(list.get(i + 1));
                list.remove(i);
                list.set(i, momentaryResult);
                ops.deleteCharAt(i);
                i--;
            }
        }
        // Check for a divide operation - if there is one, solve it.
        for (int i = 0; i < ops.length(); i++) {
            if (ops.charAt(i) == 47) {
                momentaryResult = list.get(i).divide(list.get(i + 1));
                list.remove(i);
                list.set(i, momentaryResult);
                ops.deleteCharAt(i);
                i--;
            }
        }
        // Check for a subtract operation - if there is one, solve it.
        for (int i = 0; i < ops.length(); i++) {
            if (ops.charAt(i) == 45) {
                momentaryResult = list.get(i).subtract(list.get(i + 1));
                list.remove(i);
                list.set(i, momentaryResult);
                ops.deleteCharAt(i);
                i--;
            }
        }
        // Check for a plus operation - if there is one, solve it.
        for (int i = 0; i < ops.length(); i++) {
            if (ops.charAt(i) == 43) {
                momentaryResult = list.get(i).add(list.get(i + 1));
                list.remove(i);
                list.set(i, momentaryResult);
                ops.deleteCharAt(i);
                i--;
            }
        }

        // Return with the one remaining number that represents the result.
        return list.get(0);
    }
}

编辑:或会是更容易编写一个新的code有不同的算法...

or would it be easier to write a new code with a different algorithm...?

推荐答案

我会张贴此作为注释你的问题,但我没有必要的声誉这样做。

I would post this as a comment to your question, but I do not have the required reputation to do so.

不管怎样,既然你已经认识到错误是操作员 * - 不能让你将通过更换加运算解决这个问题的方法前一个负立刻?像这样的:

Anyway, since you have already recognized that the bug is the "operator" *- couldn't you make a method that would fix this problem by replacing the plus operator immediately before by a minus? Like this:

1 + 2 * -1 >>> 1-2 * 1

。但也许这将是您更容易适应这样的解决方案,在code,它已经工作。

If you want I can write you the code. But maybe it will be easier for you to adapt a solution like this in your code that is already working.

修改 - 1

显然,code也应该把下面的情况:

Obviously, the code should also treat the following cases:

1-2 * -1 >>> 1 + 2 * 1

2 * 1 >>> -2 * 1

编辑 - 2

下面是code我设法让。让我知道如果你发现任何错误。

Here is the code I managed to make. Let me know if you find any errors.

public int countChar(String str, char chr) {
    int count = 0;
    for (int k = 0; k < str.length(); k++) {
        if (str.charAt(k) == chr)
            count++;
    }
    return count;
}

public String fixBug(String eq) {
    boolean hasBug = eq.contains("*-");
    if (hasBug) {
        String subeq;
        int indbug, indp, indm;
        eq = eq.replace("*-", "@");
        int N = countChar(eq, '@');
        for (int k = N; k > 0; k--) {
            indbug = eq.indexOf('@');
            subeq = eq.substring(0, indbug);
            indp = subeq.lastIndexOf('+');
            indm = subeq.lastIndexOf('-');
            if (indp == -1 && indm == -1) {
                eq = "-" + eq;
            } else if (indp > indm) {
                eq = eq.substring(0, indp) + '-' + eq.substring(indp + 1);
            } else {
                eq = eq.substring(0, indm) + '+' + eq.substring(indm + 1);
            }
        }
        eq = eq.replace("@", "*");
    }
    return eq;
}

这篇关于我怎么能解决这个错误,我的字符串方程convertin计算器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆