在java中乘以数字字符串

时间:2013-12-27 03:33:59

标签: java

我是编程的初学者,我一直在练习Project Euler编程问题,到目前为止我已经能够做到这一点,但这次我不得不寻求帮助。没有剧透,我试图解决的问题包括找到一个非常大的数字的总和,所以我不能把它保存在int或double中。所以我使用这个方法将两个包含数值的字符串相乘。

    private static String multiply(String a, String b) {

    // No, I'm not checking if the strings are numeric

    int subTotal = 1, extra = 0;

    String waitingString = "";
    StringBuilder number1 = new StringBuilder(a);
    StringBuilder number2 = new StringBuilder(b);
    List<String> numbers = new ArrayList<String>();
    // The reason I reverse the numbers is the for() loops
    // I don't want to count down through the numbers, that
    // would just confuse me more.
    number1.reverse();
    number2.reverse();

    for (int i = 0; i < number1.length(); i++) {

        waitingString = "";
        subTotal = Character.getNumericValue(number1.charAt(i));

        for (int j = 0; j < number2.length(); j++) {

            subTotal *= Character.getNumericValue(number2.charAt(j));
            subTotal += extra;

            char[] temp = String.valueOf(subTotal).toCharArray();
            waitingString = temp[temp.length - 1] + waitingString;

            if (subTotal >= 10 || ((j == number2.length() - 1) && (String.valueOf(subTotal).length() > 1))) {

                extra = Integer.parseInt(String.valueOf(subTotal).substring(0, temp.length - 1));

            } else {

                extra = 0;

            }

            subTotal = Character.getNumericValue(number1.charAt(i));

        }

        for (int k = 0; k < i; k++) {
            waitingString += "0";
        }

        waitingString = extra + "" + waitingString;

        numbers.add(waitingString);

    }

    // sumAll() is not the problem just in case you were wondering.
    // Because as you've read the code, I'm passing a List<String>
    // to it and as I was trying to find the error I printed the list
    // before everything to check the values and the error was already
    // there, 3 of the values are wrong.
    return sumAll(numbers);
}

测试时我自己乘以这个数字:1125899906842624。结果应该是1267650600228229401496703205376.但是我得到的是1267650600228229401607703205376.这是相差111000000000.我一直试图找到错误2天而我只是不能。 我不是在寻找替代或更好的方法来做到这一点,我只是在我的代码中找不到应该添加的错误。 如果您需要查看其余的代码,我可以提供它,请不要介意拼写/语法错误,英语不是我的母语。

3 个答案:

答案 0 :(得分:4)

不试图运行它或在调试器下查看它:看起来你正在设置一个extra变量,这是一个进位,即当你移动时应该添加到下一个产品的值在左边(原始数字,而不是相反的数字)。我可以看到的一个问题是,如果内循环中的 last 产品产生大于或等于10的内容,则计算extra;但是当你进入下一个外部循环时,extra仍然具有该值,并且当它不应该被添加到subTotal时。尝试在外部循环开始时和内部循环开始之前添加语句extra = 0;。这可能会解决问题。

P.S。通过将subTotal表示为字符串并使用它,您可以为自己做很多额外的工作。虽然我理解为什么你想为两个被乘数和产品使用字符串,subTotal是两个单位数的乘积,并且它不会大于89.所以你永远不应该有将其转换为字符串并使用字符串。因此,而不是

char[] temp = String.valueOf(subTotal).toCharArray();
waitingString = temp[temp.length - 1] + waitingString;
你可以说

waitingString = String.valueOf(subTotal % 10) + waitingString;

或类似的东西(subTotal % 10给出了当subTotal除以10时的余数,因此是subTotal的最后一位数;而不是用于计算extra的复杂代码,只需说

extra = subTotal / 10;

除以10并抛弃其余部分。你根本不应该计算String.valueOf(subTotal)

PPS。不要担心告诉您使用BigInteger的答案。如果你正在做一个真正的编程项目,那就是你要使用的。但对于学习如何编程的人来说,我认为编写一个程序来计算两个数字的乘积,这是一个很好的学习工具。

答案 1 :(得分:2)

有人评论说,这可能是BigInteger班的工作。只是说

BigInteger intA = new BigInteger(a)
BigInteger intB = new BigInteger(b)

然后致电

intA.multiply(intB) 

这将为您提供包含结果的BigInteger

答案 2 :(得分:1)

我会像这样使用BigInteger

private static String multiply(String a, String b) {
  if (a == null || b == null) {
    if (b != null) return b;
    return a;
  }
  BigInteger v = new BigInteger(a, 10);
  if (v != null) {
    BigInteger t = new BigInteger(b, 10);
    if (t != null) {
      BigInteger r = v.multiply(t);
      return r.toString();
    }
  }

  return "";
}

public static void main(String[] args) {
  String result = multiply("1125899906842624", "1125899906842624");
  String good = "1267650600228229401496703205376";
  System.out.println(result.equals(good));
}

运行时打印true