C 找出正整数的最大除数
我需要找到正整数的最大除数并输出它。除数不应为1或等于整数本身。如果是质数,则输出应为“0”。到目前为止,我有这个代码。但是它不起作用。仅当我使用“break”而不是“return0”语句时,它才起作用,但根据任务,我不应该使用break:(如何修复它?Thnx)C 找出正整数的最大除数,c,C,我需要找到正整数的最大除数并输出它。除数不应为1或等于整数本身。如果是质数,则输出应为“0”。到目前为止,我有这个代码。但是它不起作用。仅当我使用“break”而不是“return0”语句时,它才起作用,但根据任务,我不应该使用break:(如何修复它?Thnx) #include <stdio.h> int main() { int input, maxDiv; int div = 2; scanf("%d", &input); for
#include <stdio.h>
int main() {
int input, maxDiv;
int div = 2;
scanf("%d", &input);
for ( ; div <= input/2; div += 1 ) {
if ( input % div == 0 ) {
maxDiv = input / div;
return 0;
} else {
maxDiv = 0;
}
}
printf("%d\n", maxDiv);
return 0;
}
#包括
int main(){
int输入,maxDiv;
int div=2;
scanf(“%d”,输入(&I));
对于(;div也许您可以声明一个标志
#include <stdio.h>
int main() {
int input, maxDiv;
int div = 2;
char found = 0;
scanf("%d", &input);
for ( ; div <= input/2 && !found ; div += 1 ) {
if ( input % div == 0 ) {
maxDiv = input / div;
found = 1;
} else {
maxDiv = 0;
}
}
printf("%d\n", maxDiv);
return 0;
}
#包括
int main(){
int输入,maxDiv;
int div=2;
char-found=0;
scanf(“%d”,输入(&I));
对于(;div您可以这样重写它
int main(){
int input, maxDiv = 0;
int div = 2;
scanf("%d", &input);
for(; !maxDiv; div++)
if(!(input%div))
maxDiv = input/div;
printf("%d\n", ( maxDiv == 1 || input < 0 ? 0 : maxDiv ) );
return 0;
}
intmain(){
int输入,maxDiv=0;
int div=2;
scanf(“%d”,输入(&I));
对于(;!maxDiv;div++)
如果(!(输入%div))
maxDiv=输入/div;
printf(“%d\n”,(maxDiv==1 | | input<0?0:maxDiv));
返回0;
}
这是一个无限循环,只要maxDiv!=0
,它就会退出。复杂性是O(sqrt(n))
,因为总有一个小于或等于sqrt(n)的除数,所以代码一定会退出(即使输入为负)
我忘了,你必须处理输入为零的情况。当你到达sqrt(输入)
时,你可以停止循环……找到一个完美的整数sqrt函数并不难
没有很多点被2之后的所有偶数除。事实上,除了素数,没有很多点被任何东西除。不难找到小于sqrt(INT_MAX)
(46340,对于32位整数)…如果您不想运行快速筛选来生成相同的素数,那么可以免费使用素数表
和循环
maxdiv = 0 ;
i = 0 ;
sq = isqrt(input) ;
while ((maxdiv == 0) && (prime[i] < sq))
{
if ((input % prime[i]) == 0)
maxdiv = input / prime[i] ;
i += 1 ;
} ;
maxdiv=0;
i=0;
sq=isqrt(输入);
而((maxdiv==0)和&(素数[i]
假设一个合适的整数sqrt函数和一个素数表…如前所述。既然您正在寻找最大的除数,有没有理由不向后循环到2?如果没有,那么应该不需要中断语句或任何特殊逻辑来退出循环,因为您应该一直循环,直到div
为gr大于input/2
,测试每个值,直到找到最大除数
maxDiv = -1;
for (div = input / 2;
div >= 2 && maxDiv == -1;
--div)
{
if (input % div == 0)
maxDiv = div;
}
maxDiv += (maxDiv == -1);
printf ("%d\n", maxDiv);
我添加了额外的条件maxDiv
为-1,这类似于添加一个条件break
语句。如果循环结束时它仍然为-1,那么它将变为0,因为maxDiv+=1
类似于写入maxDiv=-1+1
,即0
没有任何跳转语句,例如break
,这种测试是您必须做的
另外,关于你的代码,如果我输入40,当div
为2时,if
语句将被触发,程序将结束。如果return 0
更改为break
,maxDiv
将是2,而不是20。向后循环将找到20,因为40/2=20,40%20==0。让我们将D表示为最大除数给定复合数N>1的r。
那么,显然,数字d=N/d是N的最小非平凡因子。
如果d不是一个起始数,那么d将有一个非平凡除数p
通过及物性,这意味着p是N的除数,但这一事实与d是N的最小除数的事实相矛盾,因为p
- 所以,d必须是一个素数
特别是,搜索那些小于sqrt(N)的数字是不正确的,因为,如果p是大于sqrt(N)的质数,而sqrt(N)除以N,那么N/p sqrt(N)sqrt(N)==N,这是荒谬的)
这表明,只在从2到sqrt(N)
的引物数范围内搜索N的最小除数d就足够了
为了提高效率,必须在循环之前只计算一次值sqrt(N)。
此外,它是sqrt(N)的一个粗略近似值,因此我们可以写:
#include <math.h>
#include <stdio.h>
int main(void)
{
int N;
scanf("%d",&N);
// First, we discard the case in that N is trivial
// 1 is not prime, but indivisible.
// Change this return if your want.
if (N == 1)
return 0;
// Secondly, we discard the case in that N is even.
if (N % 2 == 0)
return N / 2;
// Now, the least prime divisor of N is odd.
// So, we increment the counter by 2 in the loop, by starting in 3.
float sqrtN = fsqrt(N); // square root of N in float precision.
for(d = 3; d <= sqrtN; d += 2)
if (N % d == 0)
return N/d;
// If the loop has reached its end normally,
// it means that N is prime.
return 0;
}
#包括
#包括
内部主(空)
{
int N;
scanf(“%d”和“&N”);
//首先,我们放弃了N是平凡的情况
//1不是质数,而是不可分割的。
//如果需要,请更改此报税表。
如果(N==1)
返回0;
//其次,我们放弃了N是偶数的情况。
如果(N%2==0)
返回N/2;
//现在,N的最小素因子是奇数。
//在循环中,我们从3开始,将计数器增加2。
float sqrtN=fsqrt(N);//浮点精度中N的平方根。
对于(d=3;d如果您想避免break
,那么仍然有goto
。您也可以只更改控制循环条件的变量。在第一次返回之前添加最后一个printf?使用break没有错。它是语言的一部分,正是为此目的而设计的。@user2992672:您确定您的代码是正确的吗输出最大除数?我想它会输出第一个除数来分割输入;a好的,我看到有一些技巧。别忘了包括:)@Olayinka。它适用于正则整数,但对于素数,它会以某种方式输出1而不是0:(@user2992672)您可以轻松地调整代码以适应素数,但我已经对其进行了编辑,以处理负数输入。