时间的效果和效率

发布于 2025-02-12 17:39:40 字数 704 浏览 0 评论 0原文

我编写了两个程序,以找到一个数字的分隔线数。

第一个功能的代码少于第二个功能,但对于500 000之类的数字,它可以进行250 001迭代。

但是,具有更多代码的第二个函数可以进行800个迭代。

关于时间复杂性,哪个功能比其他功能更有效?

int divisors(int n) 
{
  int i, count = 1;
  
  for (i = 1; i <= n / 2; i++) 
  {
    if (n % i == 0)
      count ++;
  } 
  
  return count;
}


 int divisors(int nbr)
 {
    int div_1=1;
    int div_2=0;
    int n_div=0;
    
    
    do {
        
        if (nbr % div_1 == 0)
        {
            div_2 = nbr / div_1;
            if(div_1==div_2)
            {
                n_div+=1;
            }
            else
            { n_div+= 2; }
        }
        div_1 ++;

    }while(div_1<div_2);

    return n_div;
}

I have written two programs to find the number of divisors of a number.

The first function has less code than the second one but for a number like 500 000, it make 250 001 iterations.

However the second function which has more code make 800 iterations.

Which function is more efficient than the other regarding time complexity ?

int divisors(int n) 
{
  int i, count = 1;
  
  for (i = 1; i <= n / 2; i++) 
  {
    if (n % i == 0)
      count ++;
  } 
  
  return count;
}


 int divisors(int nbr)
 {
    int div_1=1;
    int div_2=0;
    int n_div=0;
    
    
    do {
        
        if (nbr % div_1 == 0)
        {
            div_2 = nbr / div_1;
            if(div_1==div_2)
            {
                n_div+=1;
            }
            else
            { n_div+= 2; }
        }
        div_1 ++;

    }while(div_1<div_2);

    return n_div;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

温柔女人霸气范 2025-02-19 17:39:40

第一个是 o(n)for(i = 1; i = 1; i&lt; i&lt; ; = n / 2; i ++)< / code>。

第二个是O(sqrt(n)),其div_2 = nbr/div_1; and } while(div_1&lt; div_2); - 较低的时间复杂性。

有足够大的n,第二个是更效率的时间。


注意:两个循环都使用a%b - 一个昂贵的操作。第二种使用a / b < / code> - 另一个昂贵的操作。良好的编译将看到附近的这两个操作,并以大约一个成本进行执行。


也许是第三个变更? (也是O(sqrt(n)))
这使用div()来计算商的弱编译器,并在一个操作中剩余,这些编译器不会将常见的/,%一起折叠。它将div_1 == div_2移至循环外部,因为它永远不会超过一次。

#include <stdlib.h>

// Untested illustrative code.
int divisors3(int nbr) {
  int count = 0;
  int divisor = 1;
  div_t qr = { .quot = n };
  // Add 2 to the count for the distinct divisor and quotient.
  while (divisor < qr.quot) {
    if (qr.rem == 0) {
      count += 2;
    }
    divisor++;
    qr = div(nbr, divisor);
  }
  // Add 1 to the count for the common divisor and quotient.
  if (divisor == qr.quot) {
    if (qr.rem == 0) {
      count++;
    }
  }
  return count; 
}

更屈服的代码可以利用Divisornbr的多因素。

The first is O(n) with its for (i = 1; i <= n / 2; i++).

The second is O(sqrt(n)) with its div_2 = nbr / div_1; and }while(div_1<div_2); - a lower time complexity.

With large enough n, the 2nd is more time efficient.


Note: Both loops use a a % b - a somewhat expensive operation. The second uses a a / b - another somewhat expensive operation. A good compile will see these two nearby operations and perform them both for the about the cost of one.


Perhaps a 3rd alterative? (Also O(sqrt(n)) )
This uses div() to compute the quotient and remainder in one operation for weak compilers that do not fold a common /, % together. It moves the div_1==div_2 to outside the loop as it never true more than once.

#include <stdlib.h>

// Untested illustrative code.
int divisors3(int nbr) {
  int count = 0;
  int divisor = 1;
  div_t qr = { .quot = n };
  // Add 2 to the count for the distinct divisor and quotient.
  while (divisor < qr.quot) {
    if (qr.rem == 0) {
      count += 2;
    }
    divisor++;
    qr = div(nbr, divisor);
  }
  // Add 1 to the count for the common divisor and quotient.
  if (divisor == qr.quot) {
    if (qr.rem == 0) {
      count++;
    }
  }
  return count; 
}

More efferent code could take advantage of divisor being a multiple factor of nbr.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文