简体   繁体   中英

Finding the number of divisors?

I wrote this code in order to find the number of the divisors of a given number. The method I am trying to implement finds all of the prime factors (which works) and takes number of similar prime numbers plus one (which gives the number of divisors).

eg 28 = 2*2 * 7 --> (2+1)*(1+1) = 6

This is my attempt:

int num = 20;
int next = 0;
int exponent = 0;
int numberOfDivisors = 1;

    start:
        for (int i = 2; i <= num; i++)
        {
            next = i;

            if (num%i == 0)
            {   
                if (i == next)
                {
                    exponent++; 
                }
                else
                {
                    numberOfDivisors *= (exponent+1);
                    exponent = 0;
                }

                if (num != i)
                {
                    num /= i;
                    goto start;
                }
            }
        }

    std::cout << numberOfDivisors << std::endl;

I just cannot figure out what I am missing.

Using goto is bad as you can see from the comments. After a little bit of clean up your code comes down to:

#include <iostream>
int main() {
  int num = 20; 
  int numberOfDivisors = 1;

  for (int i = 2; i <= num; i++)
  {
    int exponent = 0;
    while (num % i == 0) {
        exponent++; 
        num /= i;
    }   
    numberOfDivisors *= (exponent+1);
  }

  std::cout << numberOfDivisors << std::endl;
  return 0;
}

The goto isn't helpful, actually, since you're already checked for lower prime factors there's no need to put i back to 2 .

    int numberOfDivisors = 1;
    int exponent = 1;
    int i = 2;
    while (i <= num) {
        if (num%i == 0) {   
            exponent++; 
            num /= i;
        }
        else {
            numberOfDivisors *= exponent;
            exponent = 1;
            i++;
        }
    }
    numberOfDivisors *= exponent; // <-- you were missing this, mainly

The actual problem with your code that wasn't style or performance related was that your loop finished with some exponent that you never included.

There are many issues with your code (and that goto interrupting the loop is just ugly), but one major problem with your code is that right after you enter the for loop, you set next to have the same value as i .

Then, you test something (namely, if i divides num evenly, but this doesn't matter) and (here is the critical part, you test if i is equal to next , which you just set them equal.

So, your code never has the opportunity to enter the else part of the corresponding if , which is where you would multiply the number of divisors by the exponent + 1 .

As a result, your code always prints 1 , which is not what you wanted.

PS: That else may be entirely optimized out by the compiler as part of dead-code elimination, and this is what my gcc 4.7 actually does if I enable optimization -O1 or higher.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM