测试两个32位整数,m的阶乘为m!可以被n整除。如果可以,函数divides()
返回1,否则返回0。
如下面的代码,问题是当m = 2010000时,发生了错误。你能解释一下原因吗?
#include <stdio.h>
long factorial(long n){
if((n == 0) || (n == 1)) return 1;
else{
return (n * factorial(n-1));
}
}
int divides (long n,long m)
{
long facN;
printf("n=%ld ",n);
facN = factorial(n);
if(m != 0){
if(facN == 1) return 0;
else{
if(facN % m == 0) return 1;
else if((facN % m) != 0)return 0;
}
}
else if(m == 0) return 0;
}
int main()
{
printf("%d", divides(2000000,1));
}
答案 0 :(得分:2)
您需要计算已考虑模数的阶乘。使用以下标识:
(a * b) % n = ((a % n) * (b % n)) % n
我们可以将阶乘计算为:
m! % n = (((((1 % n) * 2) % n) * 3) % n) ...) % n
答案 1 :(得分:2)
32位整数只能存储0到12的阶乘。
1*2*3*4*5*6*7*8*9*10*11*12
479001600
1*2*3*4*5*6*7*8*9*10*11*12*13
6227020800
答案 2 :(得分:0)
鉴于69!您可能正在查看值溢出,但您可能也会看到内存/堆栈耗尽,因为您将在递归中嵌套200万深度。
您的支票if((facN % m) != 0)
也是多余的,因为它在else
至if(facN % m == 0)
答案 3 :(得分:0)
如果您的原因是要了解m!
m
是否可以被n
整除,请不要计算因子。
而是将n
分解为其因素,检查数字中是否有足够多的数字,范围从1
到m
,包括在内。
例如;对于m = 7
和n = 28
,流程应如下所示:
n % 2 == 0 ? yes
n /= 2
2 * 1 <= m ? yes
n % 2 == 0 still? yes
n /= 2
2 * 2 <= m ? yes
n % 2 == 0 still? no
n % 3 == 0 ? no
...
n % 7 == 0 ? yes
n /= 7
7 <= m ? yes
n reached 1, return 1
像这样的东西。如果你无法写出来,那么你可能不应该处理这个问题。不过,如果你愿意,请留下评论,我可以编辑我的答案,以包含一个有效的代码。
我正在添加一个工作示例,使用上面的逻辑来显示n
是否是m!
的除数,只是为了向您保证这一点确实有效:
#include <stdio.h>
// this function basically compares the powers of the
// prime divisors of factee and divisor
// ... returns 1 if the powers in divisor are
// ... less than or equal to the powers in factee
// ... returns 0 otherwise
int divides( long factee, long divisor ){
int amount;
for ( int i = 2; i <= factee; i++ ){
if ( divisor % i )
continue;
amount = 0;
int copy = factee;
while ( copy ){
copy /= i;
amount += copy;
}
while ( divisor % i == 0 ){
if ( !amount )
return 0;
amount--;
divisor /= i;
}
if ( divisor == 1 )
return 1;
}
return 0;
}
int main( )
{
printf( "%d", divides( 20, 10000 ) );
getchar( );
return 0;
}
amount
变量计算i
内m!
的数量。在计算它的while
循环中,在第一个循环中添加i
s的数量,然后在第二个循环中添加i * i
s的数量,并且等等,直到没有。
例如,对于m = 5
和i = 2
,m / 2
为2
,这是{{1}内因子2
的出现次数}}。然后5!
m / 2 / 2
是1
内因子2 * 2 == 4
的出现次数。然后5!
是m / 2 / 2 == 0
的计数,这会导致循环因2 * 2 * 2 == 8
遭遇而结束。
我在代码中修复了一些重要内容,删除了最外层的0
,这是我在开始时放的东西,显然忘了删除,导致潜在的无限循环。在这里,我还制作了一个功能的改进版本,通常比上面的版本运行得更快:
while
答案 4 :(得分:-1)
long可以支持-2,147,483,647到2,147,483,647范围内的值,这里2000000!超出了长期的范围,这就是显示错误的原因。