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

发布于 2024-10-29 18:16:08 字数 604 浏览 3 评论 0原文

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

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

您能为此建议我一些算法或数据结构吗

?将为电源起作用,但我还需要一种快速的方法来计算此INT的阶乘。谢谢。

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

找到最短的弦线长度,其中包含所有长n的钻头字符串(对不起,我的英语,我举例说明)。 N< = 10000,

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

的解决方案是2^n + n -1。

我解决这个问题 可以达到长度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< = n< 2^63。我们将以 mod 1000000007 计算答案。

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

I'm trying to solve a programming contest's preliminary problems and for 2 of the problems I have to calculate and print some very big integers(like 100!, 2^100).

I also need a fast way to calculate powers of this big integers.

Can you advice me some algorithms or data structures for this?(btw, I read C Interfaces and Implementations 'arbitrary precision arithmetic' section but it doesn't help for pow())

EDIT: I think exponentiation by squaring method and bit-shifting will work for power but I also need a fast way to calculate factorials for this ints. Thanks.

EDIT2: For those who are interested;

Find the shortest bit string length that includes all bit strings with length N (sorry for my english, I'll give an example). N <= 10000

For example, the shortest bit string length that includes all of bit strings of length 2(00, 01, 10, 11) is 5(11001).

My solution for this problem was 2^n + n - 1. (so I should calculate powers of 2, I think I'll use bit-shifting)

Other problem is, given the 2 lengths, find how in how many different ways you can reach the length N. For example, the input is 10, 2, 3. Then you should reach 10 with 2 and 3(for example, 2+2+2+2+2, 2+2+3+3, 3+2+2+3, 3+3+2+2...). 1 <= N < 2^63. We will calculate the anwser in mod 1000000007.

My solution was, 2x + 3y = N, so x = (N - 3y) / 2 . For y from 0 to 2*N / 3, if x is an integer, then I should calculate generalized permutation for this X and Y, total += (x+y)! / (x!*y!).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

且行且努力 2024-11-05 18:16:08

对于整数的pow通过平方求幂

For pow with integers, exponentiation by squaring

怕倦 2024-11-05 18:16:08

您可能想看看加密程序的实现(尤其是我首先想到的 GnuPG)。原因是加密函数也使用非常大的整数(所谓的多精度整数 - MPI)。这些 MPI 的存储方式是前 2 个字节说明整数的大小,后面的字节说明如何存储值。

GPG 是开源的,看看吧:)

You might want to take a look in implementations of cryptographic programs (especially GnuPG comes into my mind first). The reason is that cryptographic functions also make use of very large integers (so called MultiPrecision Integers - MPIs). These MPIs are stored in such a way that the very first 2 bytes tell how the size of the integer and the latter bytes store the value.

GPG is open-source, just have a look at it :)

燕归巢 2024-11-05 18:16:08

使用 GMP 来处理这些。它内置了阶乘支持和大幂等。除其他外,它还具有 C 和 C++ 接口。您需要 mpz_t 作为保存非常大整数的类型。

Use GMP to handle these. It has built in factorial support and large powers etc. It has a C and a C++ interface, among other things. You'll need mpz_t as a type that holds very large integers.

嘿哥们儿 2024-11-05 18:16:08

要计算幂,请使用二分算法,该算法使用指数的二进制表示形式并减少乘法的结果数量。
数据结构只是一个整数数组

To calculate powers use dihotomic algorithm which uses binary representation of exponent and reduces resulting number of multiplications.
Data structure is just an array of integers

无所的.畏惧 2024-11-05 18:16:08

对于 C 来说,类似 this 的东西可以工作,或者使用 int 或 char 数组来滚动你自己的数组,数组中的一个点代表一个数字。
<代码>[1 | 0 | 1] 或 ['1'|'0'|'1'] 表示 101 等。

For C something like this would work, or roll your own using int or char arrays, with a spot in the array representing a digit.
[1 | 0 | 1] or ['1'|'0'|'1'] for 101, etc.

我很坚强 2024-11-05 18:16:08

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

这是一个提供数字和乘法存储的类。可以添加数字的输入和输出,这很简单。

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--;
    }
};

You can store number in the folowing format: number of digits and array of digits of this number. It is a common way to deal with big numbers in programming contests.

Here is a class than provides storing of numbers and multiplication. Input and output of numbers can be added which are trivial.

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--;
    }
};
九公里浅绿 2024-11-05 18:16:08

基础数学可以将任何双精度数与双精度数相乘...

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)

Basic mathematics can do multiplication of any double with double...

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文