通过非常大的数字提高添加性能

时间:2012-06-07 14:05:39

标签: java performance biginteger

我写这个程序来计算非常大的数字而不使用任何BigInteger方法。我完成了它,它正常工作。我使用StringBuilder和大量的parseInt调用来完成它。有没有更有效的方法来做到这一点?

顺便说一下,这只是工作表,忽略糟糕的编程风格,在完成我的工作后,我会重新整理。

private String add (String x, String y)
{
    String g = "";
    StringBuilder str = new StringBuilder();
    int sum;
    double atHand = 0;
    int dif = (int)(Math.abs(x.length()-y.length())); 

    if(x.length() >= y.length())   //adding zero for equalise number of digits.
    {
        for(int i = 0; i<dif; i++)
            g += "0";
        y = g+y;    
    }
    else 
    {
        for(int i = 0; i<dif; i++)
            g += "0";
        x = g + x;
    }

    for (int i = y.length()-1; i >=0 ; i--)
    {
        sum = Integer.parseInt(x.substring(i, i+1)) +Integer.parseInt(y.substring(i,i+1)) + (int)atHand; 

        if(sum<10) 
        {
            str.insert(0, Integer.toString(sum)); 
            atHand = 0;  
        }else
        {
            if(i==0)
                str.insert(0, Integer.toString(sum)); 
            else
            {
                atHand = sum *0.1;
                sum = sum %10;  
                str.insert(0, Integer.toString(sum));
            }
        }
    }
    return str.toString();
}

1 个答案:

答案 0 :(得分:3)

不是逐个字符地进行,而是应该一次使用k个字符,这样它就可以适合Java intlong。使用一些预定的阈值,该阈值可以保持“块”,并且取决于实现,任何溢出(即,使得(threshold * 2) < positive_type_limit)。为了简化操作,请使用十进制的阈值,这样您就可以直接将其映射到基数为10的数字的字符表示中(例如,如果您的溢出阈值为一百万,那么您可以在一个时间) - 这也有额外的好处,你可以有效地将其转换回字符串。

然后你的“块”要大得多。然后,您将使用这些块和限制/阈值(基于您使用的整数基元类型)添加并执行溢出。所以基本上你是在一个ints的数组上运行。

您仍然会有O(n)的时间复杂度,但它会更小n(更具体地说,它将是O(n/k),其中k是小数位数一个数字代表的数字。)

我相信所有解决方案都涉及将大数字拆分为更小的块并对其进行操作。您已经完成了此操作,只有您当前的解决方案是blocksize=k=1的特例。

要充分利用该块,您可以使用2的幂作为限制,例如对于32位无符号整数类型,您可以将阈值设置为2^31(或者您可以将其设置为2 ^ 32,但这取决于存储溢出的位置和方式以传递给下一个元素)

如果BigInteger使用类似的技术,我不会感到惊讶。