Why is my program not printing perfect integers? - c++

I am new to C++ programming and have a problem with one of my programs
#include <iostream>
using namespace std;
bool IsPerfect(int n);
int main ()
{
for(int i=1; i<100; i++){
IsPerfect(i);
}
return 0;
}
bool IsPerfect(int n){
int sum;
for(int x=1; x<n; x++){
if(n%x==0){
sum+=x;
return true;
cout <<n;
}
else{
return false;
}
}
}
I am trying to create a program that will list perfect numbers but I can't find the bug as to why it would not print.

I see 3 issues:
Your algorithm is wrong. Your loop terminates on the first time a number is evenly divisible by any factor (including 1). See Wikipedia for an explanation of the algorithm.
You have an uninitialized variable with int sum; Also, you only ever write to it, you don't read it in a useful manner ever.
You have unreachable code. Your cout << n; in the loop will never be hit.
Try the following corrected code:
#include <iostream>
#include <cassert>
using namespace std;
bool IsPerfect(int n)
{
int sum = 1;
for(int x = 2; x < n; ++x)
{
if(n % x == 0)
sum += x;
}
return sum == n;
}
int main ()
{
for(int i=1; i<100; i++){
if (IsPerfect(i))
cout << i << endl;
}
assert(IsPerfect(6));
assert(IsPerfect(28));
assert(IsPerfect(496));
return 0;
}

You have a return statement before you output statement here:
return true;
cout <<n;
you need to swap the order of these statements, you also probably want to add a comma or some other separator:
std::cout << n << ", " ;
return true;
I am not sure that is where you want to return from since you will exit the first time you enter that if statement, which will happen when x is 1.

If you want to capture perfect numbers - numbers which are equal to the sum of their divisors, correct? - you need to allow the loop to proceed (and the sum to actually, well, sum) without returning. Take your print statement and your return statements and place them after the end of your loop; you should be checking then if the sum you have calculated is equal to n.

All these answers are telling you to write the number before returning. But that's ignoring the poor design here: you have a function that decides whether a number is perfect; it should not be that function that also decides what to do with this information (print it, store it, send it over the network, ...).
This will also make your code more readable, because the name IsPerfect is misleading - it tells the reader that this function just returns whether the number is perfect. Thus, the loop in the main function reads as, "for the integers 1 to 100, ask whether it is perfect and ignore the answer". This is not a useful program.
Remove the cout line from IsPerfect completely and put it in main instead:
for (int x = 1; x < 100; ++x) {
if (IsPerfect(x)) {
std::cout << x << '\n';
}
}

Try this
if(n%x==0){
sum+=x;
cout <<n;
return true;
}

The issue is in here:
if(n%x==0){
sum+=x;
return true;
cout <<n;
}
the keyword return immediately ends the function and returns the appropriate value (true). This means that all statements following it won't be executed. Try the following:
if(n%x==0){
sum+=x;
cout <<n;
return true;
}

In addition to the problems others have pointed out, you will never compute the right answer because you didn't initialize your sum variable.
Change
int sum;
to
int sum=0;

Related

While loop task in c++

I am a beginner in c++ and I am having problems with making this code work the way I want it to. The task is to write a program that multiplies all the natural numbers up to the loaded number n.
To make it print the correct result, I divided x by n (see code below). How can I make it print x and not have to divide it by n to get the correct answer?
#include<iostream>
using namespace std;
int main(){
int n,x=1;
int i=0;
cout<<"Enter a number bigger than 0:"<<endl;
cin>>n;
while(i<n){
i++;
x=i*x;
};
cout<<"The result is: "<<x/n<<endl;
return 0;
}
At very first a principle you best get used to as quickly as possible: Always check user input for correctness!
cin >> n;
if(cin && n > 0)
{
// valid
}
else
{
// appropriate error handling
}
Not sure, why do you need a while loop? A for loop sure is nicer in this case:
int x = 1;
for(int i = 2; i < n; ++i)
x *= i;
If you still want the while loop: Start with i == 2 (1 is neutral anyway) and increment afterwards:
i = 2;
while(i < n)
{
x *= i;
++i;
}
In case of n == 1, the loop (either variant) simply won't be entered and you are fine...
You already have two very good options, but here is an other one you might want to take a look at when you are at ease enough in programming :
unsigned factorial(unsigned value)
{
if (value <= 1)
{
return 1;
}
else
{
return value * factorial(value - 1);
}
}
It's a recursive function, which is kind of neat when used in proper moments (which could not be the case here unfortunately because the execution stack might get so big you fill your memory before you're done. But you can check it out to learn more about recursive functions)
When your memory is full, you then crash your app with what is called actually a stack overflow.
How can I make it so that in the last cout I can only put x and not have to divide x by n to get the correct answer?
It will be better to use a for loop.
// This stops when i reaches n.
// That means, n is not multiplied to the result when the loop breaks.
for (int i = 1; i < n; ++i )
{
x *= i;
}
cout << "The result is: " << x <<endl;

C++ for loop outputs different results with one array than multiple arrays

I can't understand why the outputs are different when I put 1 array into a very simple for loop and when I put two arrays into it.
int arrR[100];
int arrN[100];
//function to run the simulation
void runsim(){
for(int i=1;i<=100;i++){
arrN[i] = i;
arrR[i] = i;
}
}
//function to print the array
void printarr(int x[100]){
for(int i=0;i <= 100;i++){
cout << x[i] << ", ";
}
cout << endl;
}
int main(){
runsim();
printarr(arrR);
printarr(arrN);
return 0;
}
This outputs arrR as: 0,1,2,3,4,5,6,...,100 which is what I want, but
it outputs arrN as: 100,1,2,3,4,5,6,...,100 which I do not understand.
If I remove arrR from the for loop arrN prints how I want
int arrR[100];
int arrN[100];
//function to run the simulation
void runsim(){
for(int i=1;i<=100;i++){
arrN[i] = i;
}
}
//function to print the array
void printarr(int x[100]){
for(int i=0;i <= 100;i++){
cout << x[i] << ", ";
}
cout << endl;
}
int main(){
runsim();
printarr(arrN);
return 0;
}
This outputs arrN as 0,1,2,3,4,5,6,...,100
Interestingly, if I change all the 100's to 10's in the code this problem also goes away even if I keep both arrays in the for loop.
Can anyone help me understand what I'm missing? I'm sure it's simple because I'm pretty new to C++. Thank you!
Note the condition of for is i<=100, equals sign means you will access the array by arrN[100], then get out of the bound. This is undefined behavior, anything is possible. The valid range should be [0, N) (N = 100), i.e. arrN[0], …, arrN[N - 1] (i.e. arrN[99]).
You might want to change all the conditions to i < 100.
Please note that array indexing start from 0 instead of 1 ends at n-1 instead of n. Now in your function runsim() you are accessing the assigning value 100 to arrN[100] and arrR[100] which is not possible leads to undefined behavior.
You should change the for loop condition
for(int i = 0; i < 100; i++) {
// Do something.
}
Please note that accessing element out bound will not produce any error as well. For more detail please refer Accessing an array out of bounds gives no error

Prime number finder cannot find prime, stops after 7

So I made a simple prime number finder for the numbers between 3 and 200. It has to use a boolean variable, just fyi. No errors occur. output is:
The prime numbers between 3 and 200 are:
3
5
7
Why does it not keep going? I have drawn it out on paper time and again and cannot find my logic error.
In addition; I wrote this out by hand because I do not know how to get the contents of my file. It exists on a remote host which I do not have root access to. Is there a better way to copy the file?
#include <iostream>
using namespace std;
int main()
{
int count=0;
cout<<"The prime numbers between 3 and 200 are: "<<endl;
for (int i=3;i<=200;i++)
{
for (int j=2;j<i;j++)
{
bool ptest=i%j;
if (!ptest)
{
break;
}
else if (ptest)
{
count=count+1;
if (count==(i-2))
cout<<i<<endl;
}
}
}
}
You forgot to set count back to 0 after using it in the j loop. Move the line:
int count = 0;
to be inside the first for loop. Then your program works correctly (although as msw indicated, it is not the most efficient technique!)
Some things to consider:
You don't need to consider any even numbers in your code.
You have some logic errors in your code. The value of count needs to be checked after the second for loop. count needs to be reset before the second for loop begins.
You can stop immediately after you find the number is not prime in the inner loop instead of continuing on. You can just use a flag isPrime instead of counting.
Here's a version of the code that works for me:
#include <iostream>
using namespace std;
int main()
{
cout << "The prime numbers between 3 and 200 are: " <<endl;
for (int i=3; i <= 200; i += 2) {
bool isPrime = true;
for (int j=3; j < i; j += 2) {
if (i % j == 0) {
isPrime = false;
break;
}
}
if (isPrime)
{
cout << i << endl;
}
}
}
You don't have to loop till j reach i, instead you can check if j < sqrt(i) ,i.e. write in the second for loop: for (int j=3; j*j<=i; j+=2)

Can't figure out why this output formatting loop is going infinite

My program is supposed to take in a number from user input, determine whether or not it is prime, and then if it is not, output the factors of the entered number, 5 to a line. The 5 to the line part is where everything goes haywire, the loop i wrote should work fine as far as i can tell, however no matter how much i change it around, it does one of two things, 1) goes infinite with either new lines or the first factor, or 2) outputs a line with 5 of each factor. Here's the code:
else
{
cout << "\nNumber is not prime, it's factors are:\n";
for (int x = 2; x < num; x++)
{
factor=num%x;
if (factor==0)
{
int t=0;
cout << x << "\t";
t++;
for (int t; t <= 5; t++) // THE TROUBLE LOOP
{
if(t>=5)
{
t=0;
cout << endl;
}
}
}
}
}
Replace the declaration of t in the loop since you've declared t prior to the loop:
for(; t <= 5; t++)
With int t in the loop declaration you are overriding t as an uninitialized variable that will have a garbage value.
Outside of this problem your loop is infinite since you will be resetting t to 0 whenever it equals 5.
In the for loop change the
int t
to
t=0
it is the
for(int t,t<=5,t++)
the int t part in particular that is causing the issue.
#GGW
Or this:
int t = 0;
//some code
for(t; t <= 5; t++)
//more code

Bubble Sort program does not output result

I am in a discrete mathematics class and one of the hw problems is to implement a bubble sort. Here's my futile attempt because it does not output the solution. Please advice. Thank you.
#include <iostream>
#include <cstdlib>
using namespace std;
void BubbleSort();
int array1[100] = {0};
int k;
int main()
{
cout << "Enter your numbers and when you are done, enter 0000:\n";
int x = 0;
int i;
while (i != 0000)
{
cin >> i;
array1[x] = i;
x++;
k = x;
}
BubbleSort();
system("pause");
return 0;
}
void BubbleSort(){
int temp;
for( int i = 0; i < k; i++ ){
if ( array1[i] > array1[i+1]){
temp = array1[i+1];
array1[i+1] = array1[i];
array1[i] = temp;
}
}
int x = 0;
while (x <= k)
{
cout << array1[x] << "\n";
x++;
}
}
Please only use basic programming techniques because this is my first programming class. Thank you.
Edit: fixed the relational operator. But now I get incorrect results.
while (x >! k)
This doesn't do what you think it does. If you want something that says "while x is not greater than k", you want <=. Since array1[k] isn't one of the elements you sorted, though, you probably want <.
while (x < k)
Note that for exists for loops like these:
for (int x = 0; x < k; x++) {
cout << array1[x] << "\n";
}
As for the new bug, you're only doing one round of bubbling in your bubble sort. You need another for loop. Also, i is never initialized in main, and i != 0000 isn't going to check whether the user literally entered 4 zeros. It'll only check whether the user's input was equal to the number 0.
The primary problem is here:
while (x >! k)
On the first iteration, the condition checks whether (0 > !k), and k is not 0, so !k is 0, so the condition is false and the loop never executes. Try using:
for (int x = 0; x < k; x++)
cout << array1[x] << "\n";
You also have a problem in the sort phase of your bubble sort; you only iterate through the data once, which is not enough to sort it, in general.
Finally, some design issues.
You should have one function to sort the data and a separate function to print it. Don't combine the two functions as you have done here.
Avoid global variables. Pass the array and its operational length to the sort function, and to the print function if you have one.