I have created this C++ file that allows me to check for perfect integer numbers ranging from 1 - 1000, and then print them. I have done this, but now I am trying to include the divisors of each perfect number that prints on the screen, and I am stuck. I tried adding a void printFactors (int number), but it was just printing all the numbers and it went crazy. Any ideas, without adding another function to my code? Thanks

```
#include <iostream> //allows program to perform input and output
using std::cout; //program uses cout
using std::cin; //program uses cin
using std::endl; //program uses endl
bool perfect (int number) // declare perfect integer function
{
bool perfect;
int number1 = 0;
for (int i = 1; i != number; i++)
{
if (number%i == 0)
{
number1 += i;
}
}
if (number1 == number)
perfect = true;
else
perfect = false;
return perfect;
}//end perfect integer function
int main() //function main begins program execution
{
int number = 1000;
for (int i = 1; i <= number; i++)
{
if (perfect(i) == true)
cout << i << endl; // print i
}
return 0;
} //end main function
```

You already found the divisors here :

if (number%i == 0)

{

number1 += i;

}

In this if block, i is a divisor of number. I'm sure you can make it work with that hint :) Give it a try.

So I propose a code.

Concerning the algo, I've only change the condition of your loop in the perfect function because there is no need to go further than the half of the propose number.

```
#include <iostream>
#include <vector>
using namespace std;
bool perfect(int,vector<int>*);
int main()
{
int number = 1000;
vector<int> divisors;
for (int i = 1; i <= number; i++)
{
divisors.clear();
if (perfect(i,&divisors) == true)
{
cout << "Here is a new perfect number : ";
cout << i << endl;
cout << "And its divisors are :" << endl;
for(size_t j=0;j<divisors.size();j++)
cout << divisors[j] << endl;
}
}
return 0;
}
bool perfect(int number,vector<int>* pvec)
{
int number1 = 0;
for (int i = 1; i <= number/2; i++)
{
if (number%i == 0)
{
number1 += i;
pvec->push_back(i);
}
}
if (number1 == number)
return true;
return false;
}
```

btw, why pass a vector by pointer ? A reference would work a lot better ;)

You don't need vectors ... Just take a look at the hint in my first post ... Did that get you going ?

Think of the desired output you want, and how you can achieve that. Compare it with the output you have now, and what you need to add to get to the desired output.

I'm intentionally vague ... If I'm too vague, tell me so. But give it a try ;)

You can't print out the factors in the loop in perfect fucntion cause you won't know before loop end whether the number is perfect or not. One way out is to pass an array where the perfect function adds all factors and when perfect returned true, you could print out the factors as well by simply iterating the factors returned in the array (that is the solution kaylanraylor had posted). Infinity proposed a second way where you would have a second function whcih prints the numbers *after* you found out that it was perfect. That would be in main like:

if (perfect(i) == true)

{

cout << "perfect: " << i << " divisors: " << printdivisors(i) << endl;

The printdivisors would be much similar to the perfect function beside that it *knows* that the passed number ws perfect and therefore could output any divisor with cout:

if (number%i == 0)

{

cout << i << ' '; // prints the number + a space

What I personally don't like with that solution is that the printdivisors actually has redundant code. The array solution is fine but if you won't (can't) use dynamic arrays I would recooemnd against either.

A third way is to have the perfect function make the printouts as well:

bool find_perfect_and_print (int number)

{

...

// in case of a perfect number we have to find the divisors again

// so we have a outer loop with exactly two iterations

for (int n = 0; n < 2; ++n)

{

for (int i = 1; i < number; i++)

{

if (number%i == 0)

{

if (n == 0)

.... // add the divisor

else /* if (n == 1) */

.... // print the divisor

}

// handle case (n == 0) and return false if number isn't perfect

// if number is perfect print it and continue the loop so that it prints the divisors

...

}

return true; // if come here we actually *know* it is perfect

}

You see the function is a little bit 'bumpy' and actually it seems not to be well defined cause it makes two quite different things like calculating and printing, so I would recommend a 4th way. Here, the main idea is that the number of divisors for any (32bit) integer is 31 (factor is all 2). If we use primes for factors only (and omit the 1 as it always was factor) we see that the maximum number of prime factors for an integer is 10 (2*3*5*7*11*13*17*19*23) cause the next prime would make the product > 2^32. Because of that small number we could define a fix-sized array in the main, pass it to the perfect and let the perfect fill all the divisors:

int main() //function main begins program execution

{

int numdivisors = 0; // that is to take the number of divisors

int divisors[16] = { 0 }; // that is splendid as told above

// = { 0 } makes all elements 0

....

Then, pass the array to the perfect function (similar to that kaylanreilor posted)

if (perfect(i, divisors, numdivisors ) == true)

To make that compile the perfect has to be declared as

bool perfect(int number, int divisors[], int& numdivisors);

Note the 'int&' . It makes the numdivisors passed by reference. That way the calling function gets the value back when it was changed in the perfect.

To make the wole thing running there are only three points left todo:

1. initialized the numdivisors to 0 at begin of perfect

2. Fill the divisors array in perfect whenever you add a divisor to number1.

and increment the numdivisors.

if (number%i == 0)

{

divisors[numdivisors] = i;

++numdivisors;

.... // add to number1

3. In main when perfect(i, ....) was true, print the divisors from 0 to numdivisors-1

Regards, Alex

The code should print in the correct order because of this line :

cout << i << printDivisors(i) <<endl; // print i

that prints the perfect number first and then the divisors.

The extra 0 at the end is because it also prints the return value of the printDivisors(i) call which is a bool. Instead use this code :

if (perfect(i) == true) {

cout << i << " : ";

printDivisors(i);

cout <<endl; // print i

}

void printDivisors (int number)

{

for (int i = 1; i != number; i++)

if (number%i == 0)

{

cout << i << " ";

}

}

That's it.

Now, your code does what it needs to do, which is good !

We can make it better though ... As Alex already pointed out, you calculate the divisors twice, which is a waste of time (not to mention that it is done with two different functions).

The only way to get around this is to calculate the divisors once and store them somewhere to be used by the perfect and the printDivisors functions.

You said you hadn't learned about vectors yet. Have you learned about arrays ?

Actually, that isn't true, because the behavior is undefined. But never mind about that. With the fix I mentioned, it's all ok.

Did you make the other change I suggested too ?

if (perfect(i) == true) {

cout << i << " : ";

printDivisors(i);

cout <<endl; // print i

}

instead of :

cout << i << printDivisors(i) <<endl; // print i

There's always a way. For example, you can put the code for printing inside the perfect function ... It doesn't make a lot of sense though. Do you have a requirement to do it that way ?

>> Also do you know of a way to but a plus sign in between the divisors?

Sure. Right now, you put a space between the values :

cout << i << " ";

You just have to replace that space with a +

>> I too am trying to be vague incase someone else needs to learn this also, but I can include my code if it would help you answer this question.

Well, it IS your question, so you don't have a reason to be vague ;) It's admirable though, but right now, the main goal is to help you :)

Just one thing : if anything is not clear, then please ask about it. It's best to understand the way the code works. Feel free to ask anything, no matter how silly it might seem.

Then I assume it's not bad to have them in two functions.

If you do want them in one, then you can do that of course. Just put everything into one function.

>> wouldn't that make it so when the perfect numbers display they will have the + sign and not the divisors?

Depends which one you modify ;) Of course you have to modify the one that prints the divisors. Note that you'll also have to account for the last one, because you don't want a trailing +.

The trick is to treat the first divisor differently inside the loop.

Right now, this code prints the divisors :

for (int i = 1; i != number; i++)

if (number%i == 0)

{

cout << i << " + ";

}

If we put the + before the i :

cout << " + " << i;

and make sure that the first divisor is printed like this :

cout << i;

then the output will be good.

So, how do we distinguish the first divisor from the others ? That's easy. The first divisor is always 1. I'm sure that hint will help you :)

Give it a try ...

## Premium Content

You need an Expert Office subscription to comment.Start Free Trial