如何处理不适合任何语言数据结构的大整数

时间:2011-04-04 21:00:55

标签: c algorithm data-structures biginteger arbitrary-precision

我正在尝试解决编程竞赛的初步问题以及我必须计算的两个问题并打印一些非常大的整数(例如100!,2 ^ 100)。

我还需要一种快速的方法来计算这个大整数的幂。

你能为我建议一些算法或数据结构吗?(顺便说一下,我读过C接口和实现的'任意精度算术'部分,但它对pow()没有帮助)

编辑:我认为通过平方法和位移的取幂对功率起作用,但我还需要一种快速的方法来计算这个因子的阶乘。感谢。

EDIT2:对于那些感兴趣的人;

找到包含长度为N的所有位串的最短位串长度(对不起我的英文,我举一个例子)。 N <= 10000

例如,包含长度为2(00,01,10,11)的所有位串的最短位串长度为5(11001)。

我对这个问题的解决方案是2 ^ n + n - 1.(所以我应该计算2的幂,我想我会使用位移)

其他问题是,给定2个长度,找到你可以用多少种方式达到长度N.例如,输入是10,2,3。那么你应该用2和3达到10(例如,2 + 2 + 2 + 2 + 2,2 + 2 + 3 + 3,3 + 2 + 2 + 3,3 + 3 + 2 + 2 ......)。 1&lt; = N&lt; 1 2 ^ 63。我们将在mod 1000000007中计算anwser。

我的解决方案是,2x + 3y = N,所以x =(N - 3y)/ 2。对于从0到2 * N / 3的y,如果x是一个整数,那么我应该计算这个X和Y的广义置换,总计+ =(x + y)! /(x!* y!)。

7 个答案:

答案 0 :(得分:6)

对于带有整数的powexponentiation by squaring

答案 1 :(得分:1)

为了计算功率,使用使用指数的二进制表示的二分法算法并减少所得的乘法数。 数据结构只是一个整数数组

答案 2 :(得分:1)

您可能希望了解加密程序的实现(尤其是首先出现在我脑海中的GnuPG)。原因是加密函数也使用非常大的整数(所谓的MultiPrecision Integers - MPI)。这些MPI以这样的方式存储,即前2个字节表示整数的大小和后面的字节如何存储该值。

GPG是开源的,只需查看它:)

答案 3 :(得分:1)

使用GMP来处理这些问题。它内置了阶乘支持和大功率等。它还具有C和C ++接口。您需要mpz_t作为包含非常大的整数的类型。

答案 4 :(得分:0)

对于C,像this这样的东西可以工作,或者使用int或char数组滚动自己,在数组中有一个代表数字的点。 对于101等,[1 | 0 | 1]['1'|'0'|'1']

答案 5 :(得分:0)

您可以按以下格式存储号码:该号码的位数和数字位数。这是在编程竞赛中处理大数字的常用方法。

这是一个提供数字和乘法存储的类。可以添加数字的输入和输出,这是微不足道的。

class huge {
public:
    int size;
    int data[1000];

    friend void mul(const huge &a, int k, huge &c) {
        c.size = a.size;
        int r = 0;
        for (int i = 0; i < a.size; i++) {
            r += a.data[i] * k;
            c.data[i] = r % 10;
            r = r / 10;
        }
        if (r > 0) {
            c.size++;
            c.data[c.size - 1] = r;
        }
        while (c.size > 1 && c.data[c.size - 1] == 0)
            c.size--;
    }

    friend void mul(const huge &a, const huge &b, huge &c) {
        c.size = a.size + b.size;
        memset(c.data, 0, c.size * sizeof(c.data[0]));
        for (int i = 0; i < a.size; i++) {
            int r = 0;
            for (int j = 0; j < b.size; j++) {
                r += a.data[i] * b.data[j] + c.data[i + j];
                c.data[i + j] = r % 10;
                r /= 10;
            }
            if (r > 0)
                c.data[i + b.size] = r;
        }
        while (c.size > 1 && c.data[c.size - 1] == 0)
            c.size--;
    }
};

答案 6 :(得分:0)

基础数学可以将任何双倍乘法加倍...

def biginteger(num1, num2):
result = []
lnum1 = len(num1)
lnum2 = len(num2)

k = x = remainder = 0
while len(result) < lnum1:
    result.append(0)
for i in range(lnum1, 0, -1):
    multiplier = int(num1[i - 1])
    for j in range(lnum2, 0, -1):
        temp = (int(num2[j - 1]) * multiplier) + remainder + int(result[k])
        result[k] = str(temp % 10)
        remainder = temp / 10
        k += 1
    result.append(str(remainder))
    if remainder != 0:
        remainder = 0
    x += 1
    k = x

return ''.join([result[i - 1] for i in range(len(result), 0, -1)])

num1 = '37234234234234'
num2 = '43234234234232'
print biginteger(num1, num2)