# how to get accumulated total in for loop

sumoffactors += (x+y);

when I use this in my nested loop it tallys the total of x+y first on number 20, then moves on to 21 etc. These have to be a total individual to each number. Am I putting this in the wrong place?
###### Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Commented:
Every time you move from one number in the range to another, you are starting over with the sum. So, you have to initialize sumoffactors to whatever worked for the number 20. I am guessing that you initialized it to either to 0 or to 1. If this explanation is not clear, I can take a look at your code. I'm sure it will be easy to fix.

Just a tip on naming conventions - try one of these styles to make it easier to read: sum_of_factors or sumOfFactors.

You explained that you are a beginner student in C++. Are you at the point where you are comfortable working with classes, functions, or just at the basics for now. Reason I asked is that your previous program was all done in the main function. A basic programming approach is to begin to think in a more building block manner - a modular manner. This allows you to think about just a small component in a large program where the component may not appear to be overwhelming. This is the approach required by many companies when writing large programs.
0
Author Commented:
I'm not sure I follow how I can initialize sumoffactors for each number. Right now I only put it within the if statement.
``````#include <iostream>
#include <iomanip>

using namespace std;
int main()

{
int range = 0,
input= 0,
sumoffactors = 0,
range1 = 0,
range2 = 0,
factor = 0,
sum = 0;
char retry;
string type;

do
{
cout << "Please choose a range: (1-3) " << endl;
cout << "1: 20-30" << endl;
cout << "2: 490-500" << endl;
cout << "3: 8120-8130" << endl;
cin >> range;

switch (range)
{
case 1:
range1 = 20;
range2 = 30;

break;

case 2:
range1 = 490;
range2 = 500;

break;

case 3:
range1 = 8120;
range2 = 8130;

break;
}

for (int i = range1; i <= range2; i++){

for (int x=2; x<i; x++){

for (int y=2; y<i; y++){

factor = x*y;

if(factor == i && x >= y){

sumoffactors += (x+y);

cout << "Number ---  Classification" << endl;

cout << i << "\t\t" << x << "\t" << y << "\t" << range2 << "\t" << sumoffactors << endl;

}
}
}
}

cout << "Would you like to try again?" << endl;
cin >> retry;
} while (retry == 'Y' || retry == 'y');

system("pause");           return 0;
}

``````
0
Commented:
You are defining new range values, right? Exactly at what line number are you defining a new range value, 21, after you are done processing the number 20?

BTW - I mentioned once that your range covers 11 integers, not 10 as you originally posted in earlier question. Is that OK as far as your assignment goes?
0
Author Commented:
ok so I put the sumoffactors=0 in each statement which seems to make the number start over. The problem I'm seeing now is it lists out each set of factors and their sums in pairs of two.

i threw in some code to figure out the abundant/deficient/perfect but since the sums are seperate it thinks each number is deficient

Number ---  Classification
20              5       4       30      9
20      Deficient
Number ---  Classification
20              10      2       30      12
20      Deficient
Number ---  Classification
21              7       3       30      10
21      Deficient
Number ---  Classification
22              11      2       30      13
22      Deficient
Number ---  Classification
24              6       4       30      10
24      Deficient
``````for (int i = range1; i <= range2; i++){

for (int x=2, sumoffactors=0; x<i; x++){

for (int y=2, sumoffactors=0; y<i; y++){

factor = x*y;

if(factor == i && x >= y){

sumoffactors += (x+y);
``````
0
Commented:
I noticed that your sum of factors for the number 20 is 21. Didn't you say that you needed to include the trivial factor 1 in this value? If so, then why not initialize the sum of factors to 1 instead of 0. This is because in your for-loop, you are correctly (in my opinion) skipping over the 1 by initializing x and y to 2.
0
Commented:
Note: my previous comment about sum of factors being off by 1 was on your OP, not the code posted in http:#28410654.

>> i threw in some code to figure out the abundant/deficient/perfect
I don't see this new code. Could you post your entire program in the Code box, so that we're in sync.
0
Author Commented:
Sum of factors set to 1 would be fine if it added it to the total sum but I'm still facing multiple sums for each number now, in which case it's adding 1 multiple times as well
0
Commented:
You have rightly initialized the sum of factors at the **START** of each new number in the range.

Your classification is done only at the **END** of computing the sum of factors. That is the classification is done only once.
0
Author Commented:

``````#include <iostream>
#include <iomanip>

using namespace std;
int main()

{
int range = 0,
input= 0,
sumoffactors = 0,
range1 = 0,
range2 = 0,
factor = 0,
sum = 0;
char retry;
string type;

do
{
cout << "Please choose a range: (1-3) " << endl;
cout << "1: 20-30" << endl;
cout << "2: 490-500" << endl;
cout << "3: 8120-8130" << endl;
cin >> range;

switch (range)
{
case 1:
range1 = 20;
range2 = 30;

break;

case 2:
range1 = 490;
range2 = 500;

break;

case 3:
range1 = 8120;
range2 = 8130;

break;
}

for (int i = range1; i <= range2; i++){

for (int x=2, sumoffactors=0; x<i; x++){

for (int y=2, sumoffactors=0; y<i; y++){

factor = x*y;

if(factor == i && x >= y){

sumoffactors += (x+y);

cout << "Number ---  Classification" << endl;

cout << i << "\t\t" << x << "\t" << y << "\t" << range2 << "\t" << sumoffactors << endl;

if (sum > i){
cout << i << "\t\t" << "Abundant" << endl;
}
if (sum < i){
cout << i << "\t\t" << "Deficient" << endl;
}
if (sum == i){
cout << i << "\t\t" << "Perfect" << endl;
}                 }
}
}
}

cout << "Would you like to try again?" << endl;
cin >> retry;
} while (retry == 'Y' || retry == 'y');

system("pause"); // forces DOS window to pause to allow user to utilize program
return 0;
}

``````
0
Commented:
>> You have rightly initialized the sum of factors at the **START** of each new number in the range.

oops, I saw that you put the sumoffactors in the for x-loop, and didn't look further. You are initializing sumoffactors twice, also in the for y-loop. The y-loop is not the start of the new number.

Also, put the classification at the end of figuring out what the sum of factors is for a number (and before you start a new number).
0
Commented:
Maybe it would be clearer if you initialized sum of factors not in any for-loop (even though the x-loop is correct), but instead one of these options:
- between the for i-loop and the for x-loop
- when you do the i++ in the for expression

I noticed that you are testing for sum, but you only initialize it to 0. Didn't you mean to test sum of factors instead?
0
Author Commented:
so it's properly adding the sums of each number now and starting over for each. I'm not sure how I can avoid having multiple lines for the numbers that have multiple sets of factors.

I changed those comparisons from sum to sumoffactors as well.

Is relocating the initialization of sum of factors causing any issues right now? I took it out of the y loop and it seemed to make the factors add properly
0
Commented:
I'll be back in 2-3 hours to see if you have any questions.

Recall in previous link, I found copied the abundant answers from wiki:
For testing, I would make the range from 1 to 103 and see if you get "Abundant" for the following N:
12, 18, 20, 24, 30, 36, 40, 42, 48, 54, 56, 60, 66, 70, 72, 78, 80, 84, 88, 90, 96, 100, 102, …

After making the minor changes noted above (and commenting out all but the useful end results), I got some additional abundant numbers. But the list is close. We can debug those cases later after you make the improved post. Here are the results for the range 2..106:

``````4               Abundant
6               Perfect ****
12              Abundant
16              Abundant
18              Abundant
20              Abundant
24              Abundant
28              Perfect
30              Abundant
36              Abundant
40              Abundant
42              Abundant
48              Abundant
54              Abundant
56              Abundant
60              Abundant
64              Abundant
66              Abundant
70              Abundant
72              Abundant
78              Abundant
80              Abundant
84              Abundant
88              Abundant
90              Abundant
96              Abundant
100             Abundant
102             Abundant
104             Abundant
``````
0
Commented:
If you can post in the next few minutes I'll try to take a quick-look at your code.

>> I'm not sure how I can avoid having multiple lines for the numbers that have multiple sets of factors.
Well, if you are looking for just end results like I posted above , then just do a single cout like I did above after your double for-loop on x and y.

IMO, no need to print out deficient - it is deficient if the number is not listed; but maybe that's a requirement.

Do you care about printing out the actual factors? If so, then just do:

20:  5    4
20:  10  2
21:  7   3
etc.

0
Author Commented:
well even after I take away the factors to only list Number and Classification it still lists 20 for instance more than once and labels it deficient more than once (same amount of lines it took to list factors)
``````#include <iostream>
#include <iomanip>

using namespace std;
int main()

{
int range = 0,
input= 0,
sumoffactors = 0,
range1 = 0,
range2 = 0,
factor = 0,
sum = 0;
char retry;
string type;

do
{
cout << "Please choose a range: (1-3) " << endl;
cout << "1: 20-30" << endl;
cout << "2: 490-500" << endl;
cout << "3: 8120-8130" << endl;
cin >> range;

switch (range)
{
case 1:
range1 = 20;
range2 = 30;

break;

case 2:
range1 = 490;
range2 = 500;

break;

case 3:
range1 = 8120;
range2 = 8130;

break;
}

cout << "Number ---  Classification" << endl;

for (int i = range1; i <= range2; i++){

for (int x=2, sumoffactors=0; x<i; x++){

for (int y=2; y<i; y++){

factor = x*y;

if(factor == i && x >= y){

sumoffactors += (x+y);

//  cout << i << "\t\t" << x << "\t" << y << "\t" << range2 << "\t" << sumoffactors << endl;

if (sumoffactors > i){
cout << i << "\t\t" << "Abundant" << endl;
}
if (sumoffactors < i){
cout << i << "\t\t" << "Deficient" << endl;
}
if (sumoffactors == i){
cout << i << "\t\t" << "Perfect" << endl;
}                 }
}
}
}

cout << "Would you like to try again?" << endl;
cin >> retry;
} while (retry == 'Y' || retry == 'y');

system("pause"); // forces DOS window to pause to allow user to utilize program
return 0;
}
``````
0
Commented:
>> int x=2, sumoffactors=0
Because you have the int, this means that you are redefining sumoffactors in the for-loop. That is, you are creating a new variable in the for-loop block, sumoffactors, that hides the original definition of sumoffactors at line 10. So, just move the initialization of sumoffactors to just after the for-i loop (but no int).

At the end of each right } brace, add the following:
} // END if factor == i
} // END for y
} // END for x
} // END for i
Verify that you have this correct using the matching brace key
-- on Visual Studio, it is CTRL + }
Then you want to put the cout classification between:
} // END for x
// the factors have been computed here, so classify
} // END for i

I see you are still initializing the sum of factors to 0.
Be back in a couple hours to see your results. Here is what I have:
``````Please choose a range: (1-3)
1: 20-30
2: 490-500
3: 8120-8130
1
Number ---  Classification
20              Abundant
21              Deficient
22              Deficient
23              Deficient
24              Abundant
25              Deficient
26              Deficient
27              Deficient
28              Deficient
29              Deficient
30              Abundant
Would you like to try again?
y
1: 20-30
2: 490-500
3: 8120-8130
2
Number ---  Classification
490             Abundant
491             Deficient
492             Abundant
493             Deficient
494             Deficient
495             Deficient
496             Deficient
497             Deficient
498             Abundant
499             Deficient
500             Abundant
Would you like to try again?
y
1: 20-30
2: 490-500
3: 8120-8130
3
Number ---  Classification
8120            Abundant
8121            Deficient
8122            Deficient
8123            Deficient
8124            Abundant
8125            Deficient
8126            Deficient
8127            Deficient
8128            Deficient
8129            Deficient
8130            Abundant
Would you like to try again?
``````
0

Experts Exchange Solution brought to you by

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Commented:
Notice in http:#28414988 that 4 and 64 were on your abundant program output, but were not listed in the Wiki list. These two just happen to be perfect squares. Coincidence? Looks like there is a little more work to be done to handle these cases.
0
Author Commented:
everything works great now, sumoffactors being 1 allowed the perfect numbers to show up. Turns out there are very few perfect numbers, I can see why these ranges were chosen now

"You wanted a list of perfect numbers. Well, as of 1990 (that is the
date of my source), there were 30 known perfect numbers, beginning
with 6, 28, 496, 8128, 33550336, and so on."

You were really helpful, the nested for loops were a bit confusing, thanks!
``````#include <iostream>
#include <iomanip>

using namespace std;
int main()

{
int range = 0,
input= 0,
sumoffactors = 0,
range1 = 0,
range2 = 0,
factor = 0,
sum = 0;
char retry;
string type;

do
{
cout << "Please choose a range: (1-3) " << endl;
cout << "1: 20-30" << endl;
cout << "2: 490-500" << endl;
cout << "3: 8120-8130" << endl;
cin >> range;

switch (range)
{
case 1:
range1 = 20;
range2 = 30;

break;

case 2:
range1 = 490;
range2 = 500;

break;

case 3:
range1 = 8120;
range2 = 8130;

break;
}

cout << "Number ---  Classification" << endl;

for (int i = range1; i <= range2; i++){
sumoffactors=1;
for (int x=2; x<i; x++){

for (int y=2; y<i; y++){

factor = x*y;

if(factor == i && x >= y){

sumoffactors += (x+y);

//  cout << i << "\t\t" << x << "\t" << y << "\t" << range2 << "\t" << sumoffactors << endl;

} // END if factor == i
}  // END for y
}  // END for x
if (sumoffactors > i){
cout << i << "\t\t" << "Abundant" << endl;
}
if (sumoffactors < i){
cout << i << "\t\t" << "Deficient" << endl;
}
if (sumoffactors == i){
cout << i << "\t\t" << "Perfect" << endl;
}  // END for i

}

cout << "Would you like to try again?" << endl;
cin >> retry;
} while (retry == 'Y' || retry == 'y');

system("pause"); // forces DOS window to pause to allow user to utilize program
return 0;
}

``````
0
Commented:
>> the nested for loops were a bit confusing
They can be confusing. You had 3 of them. One way to simplify the problem would be to define a function that takes in an integer N, and then it figures out the factors and classifies the number.

Breaking the problem down into smaller sub-problems is a very important step in developing even longer or just more complicated programs.

That idea of adding the // END for i after the right } is not just for you. When I inherited code on the job that wasn't working, I often did comment on the right } especially when there were many nested loops that spanned long distances.
0
Commented:
4: 50000-50009
Number ---  Classification
50000           Abundant
50001           Deficient
50002           Deficient
50003           Deficient
50004           Abundant
50005           Deficient
50006           Deficient
50007           Deficient
50008           Abundant
50009           Deficient
Last run took 76 seconds

But you can do better. With a series of changes in the triple loop, I got it down to 38 seconds, and then down to 8 seconds. Then I wrote it in two loops and it took under 1 second.

Then using the improved triple loop, I ran a longer scenario:
6: 100000-100009
7: 500000-500009
6
Number ---  Classification
100000          Abundant
100001          Deficient
100002          Abundant
100003          Deficient
100004          Deficient
100005          Deficient
100006          Deficient
100007          Deficient
100008          Abundant
100009          Deficient
Last run took 34 seconds

But then running the two loop version:
Number ---  Classification
500000          Abundant
500001          Deficient
500002          Deficient
500003          Deficient
500004          Abundant
500005          Deficient
500006          Deficient
500007          Deficient
500008          Deficient
500009          Deficient
Last run took 0 seconds
Again, it took under 1 second.

Now, if you are interested in seeing how you can improve your program for performance, then by all means, ask a related question, and you will get lots of help. The most instructive path would be to make one small change at a time, and rerun the program to see the improvement.

I also would encourage you to ask how to modularize your program to improve the appearance and ease in coding. I think the triple loop version took us for a loop. :)

In any case, I wish you the best of luck in your studies.
``````#include <time.h>
// GET START TIME DURATION
time_t startTime = time(0);

// GET STOP TIME DURATION
time_t stopTime = time(0);
time_t durationSeconds = (stopTime - startTime);
cout << "Last run took " << durationSeconds << " seconds" << endl;
``````
0
Author Commented:
The concept of my next chapter is breaking programs up into a set of manageable functions and making more modular, hopefully I'll be able to structure my following programs a little more efficiently going forward.
0
Commented:
>> more modular ... a little more efficiently
By efficiently, in this context it means I think the ease in which you can program the assignment.

In my previous comments on performance improvements (another way to say more efficiently), now it's just the duration of the program that's a factor.

A more modular approach is usually very good for your own efficient approach to designing more complex programs, and is usually essential in helping others in a team to come in a work together to fix or add functionality to the program. But it can even result in inefficiencies in the performance of the program.

So, if you would like to see how to improve the timing from 78 seconds down to 38 seconds down to 8 seconds and finally under 1 second, then that might be a very interesting question for you to ask. But if you are overloaded with work, then it can wait for another day.
0
###### It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.