无需使用外部库即可优化处理极大数量的方法

时间:2013-05-21 05:00:43

标签: c algorithm math

处理n ^ n(1≤n≤10^ 9)的优化方式

我使用了long long int,但它不够好,因为值可能是(1000 ^ 1000)

搜索并找到GMP library http://gmplib.org/BigInt class,但不想使用它们。 我正在寻找一些处理此问题的数值方法。

我需要打印n^n 的第一个和最后一个 k (1≤k≤9)个数字

对于第一个 k 数字,我得到的如下所示(这有点丑陋的方式)

num = pow(n,n);
while(num){
    arr[i++] = num%10;
    num /= 10;
    digit++;
}
while(digit > 0){
    j=digit;
    j--;
    if(count<k){
        printf("%lld",arr[j]);
        count++;
    }
    digit--;
}

以及最后的 k 数字使用num % 10^k,如下所示。

findk=pow(10,k);
lastDigits = num % findk;
enter code here

k的最大值是9.所以我最多只需要18位数。 我想到的是获得那些18位数而没有真正解决完整的n ^ n表达式。

任何想法/建议??

3 个答案:

答案 0 :(得分:5)

// note: Scope of use is limited.

#include <stdio.h>

long long powerMod(long long a, long long d, long long n){
// a ^ d mod n
    long long result = 1;
    while(d > 0){
        if(d & 1)
            result = result * a % n;
        a = (a * a) % n;
        d >>=1;
    }
    return result;
}

int main(void){
    long long result = powerMod(999, 999, 1000000000);//999^999 mod 10^9
    printf("%lld\n", result);//499998999

    return 0;
}

答案 1 :(得分:4)

查找最不重要的数字(最后的k位数)很容易,因为模块化算术的属性表示:(n*n)%m == (n%m * n%m)%m,因此BLUEPIXY后跟exponentiation by squaring method显示的代码将找到k LSD很有效。

现在,N^N的最重要数字(第1位数字)可以通过这种方式找到:

 We know, 
 N^N = 10^(N log N)

因此,如果您计算N log (N),您将得到一些此格式xxxx.yyyy,现在我们必须使用此数字作为10的幂,很容易理解xxxx或整数​​部分数字会在10后添加xxxx零,这对你来说并不重要!这意味着,如果您计算10^0.yyyy,您将获得您正在寻找的那些重要数字。 所以解决方案将是这样的:

double R = N * log10 (N);
R = R - (long long) R; //so taking only the fractional part
double V = pow(10, R);
int powerK = 1;
for (int i=0; i<k; i++) powerK *=10;
V *= powerK;
//Now Print the 1st K digits from V

答案 2 :(得分:0)

为什么不想使用bigint个库?

bignum算法很难正确有效地完成。你仍然可以通过研究这个主题来获得博士学位。

拳头,bigint算术具有非平凡的算法

然后,bigint实现通常需要一些机器指令(比如add with carry),这些指令在普通的C中不易访问。

对于您的具体问题( N N 的第一位和最后几位数字),您最好还在纸上(使用算术定理)来降低复杂性。我不是专家,但我想这仍然是难以处理的,可能复杂性比 O(N)

更糟糕