找出正整数的最大除数

时间:2014-08-02 16:32:20

标签: c

我需要找到正整数的最大除数并输出它。除数不应为1或等于整数本身。如果它是素数,则输出应为" 0"。到目前为止我有这个代码。然而,它不起作用。它只适用于我使用" break"而不是"返回0"声明,但根据任务我不应该使用break :(我该如何解决?Thnx

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

5 个答案:

答案 0 :(得分:4)

你可以这样重写

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

这是一个无限循环,会在maxDiv != 0后立即退出。复杂度为O(sqrt (n)),因为总是有一个n小于或等于sqrt(n)的除数,因此代码必然会退出(即使输入是负数)。

我忘了,你必须处理输入为零的情况。

答案 1 :(得分:1)

也许你可以宣布一个旗帜?

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

答案 2 :(得分:0)

当你到达sqrt(input)时,你可以停止循环......找到一个完美的整数sqrt函数并不困难。

除了素数以外,除了所有偶数之外没有太多的分数。事实上,除了素数之外没有太多的点除以。找到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 ;
     } ;

假设一个合适的整数sqrt函数和一个素数表......如上所述。

答案 3 :(得分:0)

既然你正在寻找最大的除数,你有没有理由不向后循环到2?如果没有,则应该不需要break语句或任何特殊逻辑来退出循环,因为你应该保持循环直到div大于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,if语句将在div为2时触发,程序将结束。如果return 0更改为break,则maxDiv将为2,而不是20.向后循环将找到20,因为40/2 = 20,40%20 == 0。 / p>

答案 4 :(得分:0)

让我们将 D 表示给定复合数 N&gt;的最大除数。 1
那么,显然,数字 d = N / D N 的最小非平凡除数。
如果 d 不是引物编号,那么 d 将具有非平凡的除数 p&lt; d
通过传递性,这意味着 p N 的除数,但这个事实与 d N ,因为 p&lt; d

  • 因此, d 必须是素数。

特别是,搜索那些小于 sqrt(N)的数字是很有意义的,因为如果 p 是一个大于的素数sqrt(N)除以 N ,然后 N / p <= sqrt(N)(如果没有,* p *(N / p)&gt; ; sqrt(N) sqrt(N)== N ,这是荒谬的)。

这表明只需在2到{{1}的引物号范围内搜索 N 的最小除数 d 就足够了}。

为了提高效率,值 sqrt(N)必须在循环之前计算一次。
此外,它足够粗略近似 sqrt(N),所以我们可以写:

sqrt(N)

我认为这个问题没有得到很好的说明,因为我认为用一个更好的标志来表示 N 是素数将是1的返回值。

有更有效的算法来确定素数,但它们超出了本问题的范围。