【问题标题】:smallest divisor of an integer without computing the square root explcitly不显式计算平方根的整数的最小除数
【发布时间】:2012-07-28 08:56:49
【问题描述】:

此代码给出整数的最小除数。但问题是我必须计算平方根。有没有办法让我不必显式计算平方根?

int d,r,n;
scanf("%d",&n);
if(n%2==0)
{
    printf("2 is ans"); 
}
else
{
    r=sqrt(n);
    d=3;
    while((n%d!=0)&&d<r)
    {
        d=d+2; 
    }
    if(n%d==0)
        printf("ans is %d",d);
    else
        printf("ans is 1");
}

【问题讨论】:

    标签: c algorithm performance


    【解决方案1】:

    由于code-efficiency 是其中一个标签,所以稍微调整一下提供的答案:

    while ((n%d) && (d<n/d)) d+=2;
    

    编译器更有可能以这种方式重用除法运算符的结果。

    在我建议的循环版本上查看gcc -O3 的编译器输出,每次迭代只有一个除法运算,结果用于两个比较:

    L18:
            cmpl    %esi, %ecx
            jle     L13
            movl    %ebx, %eax
            addl    $2, %esi
            cltd
            idivl   %esi
            testl   %edx, %edx
            movl    %eax, %ecx
            jne     L18
            .p2align 4,,15
    L13:
    

    虽然,while ((n%d) &amp;&amp; d*d &lt; n) d+=2; 版本给出:

    L8:
            movl    %ecx, %eax
            imull   %ecx, %eax
            cmpl    %ebx, %eax
            jge     L3
            movl    %ebx, %eax
            addl    $2, %ecx
            cltd
            idivl   %ecx
            testl   %edx, %edx
            jne     L8
            .p2align 4,,15
    L3:
    

    很明显,每次迭代都在进行乘法和除法。

    【讨论】:

      【解决方案2】:

      当然。而不是这个:

      while((n%d!=0)&&d<r)
      

      你可以写

      while((n%d!=0) && d*d < n)
      

      【讨论】:

      • 虽然请注意,计算一次 sqrt 实际上可能比在循环中进行乘法更好。
      • 乘法也可以保存在变量中。此外,编译器可能会自动执行此操作。
      • 不,因为d每次迭代都会改变,它的平方也必须每次迭代计算。
      • 无论如何,哪一个肯定会更好??计算平方根或使用乘法。
      • 你最好考虑 user315052 的回答。
      【解决方案3】:

      您可以检查d*d &lt; n,而不是检查d &lt; sqrt(n),所以:

      while((n%d!=0)&&d<r)
      

      应该是

      while((n%d!=0) && d*d < n)
      

      【讨论】:

        【解决方案4】:

        该算法使用平方根来减少循环中的迭代次数。大大减少。我不知道平方根有什么问题,但是您可以用these algorithms 近似计算平方根,或者只是将d 更改为d * dr 更改为n 在这一行while((n%d!=0)&amp;&amp;d&lt;r) 或只是将r 更改为n(但性能下降)

        【讨论】:

        • 确保使用平方根可以减少迭代次数。只是我希望它不应该明确计算,而是应该在旅途中使用它。
        猜你喜欢
        • 1970-01-01
        • 2014-03-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-30
        • 1970-01-01
        • 2018-12-07
        相关资源
        最近更新 更多