C++ Printing Odd numbers instead of Prime Numbers - c++

I have been working on an assignment question for days and cannot seem to get the correct output (I've tried so many things!) The question is:
Write a program that uses two nested for loops and the modulus operator (%) to detect and print the prime numbers from 1 to 10,000.
I have been doing from 1 to 10 as a small test to ensure its working. I am getting 2,3,5,7,9 as my output, so I know something is wrong. When I increase the number from 10 to 20 it is printing 2 plus all odd numbers. I am including my code below. Thanks!!
int main() {
for (int i=2; i <=10; i++){
for (int j=2; j<=i; j++){
if (i%j==0 && j!=i) {
break;
}
else {
cout<< i <<endl;
break;
}
}
}
}

In addition to Sumit Jindal's answer inner for loop can be done by this way as well:
for(int j=2; j*j<=i ; j++)
If we think about every (x,y) ordered pair that satisfies x*y = i, maximum value of x can be square root of i.

The problem lies in the if-else branch. Your inner loop will be run exactly once because it will break out of the inner loop as a result of your if else branch.
When you first enter the inner loop the value of j is 2. Your condition will test if variable i is divisible by 2. If it is it breaks. Other wise (your else branch) will print the value of i and breaks out.
Hence printing odd numbers.
Break out of the inner loop and check whether j equals i in outer loop. You have to make j available for outer loop.

Your print statement is within the inner loop, and it should not be - it's only a prime if you run all the way through the inner loop without finding a divisor.
As a second point, you only need to check for divisors up to the square root of i, not all the way up to i.

You are breaking the inner loop after the first iteration itself, which is checking if the number(ie i) is different from j and is divisible by 2 or not (since j=2 for the first iteration)
I am getting 2,3,5,7,9 as my output
This is because every odd number fails the if and is printed in else condition

A minor correction in your code, adding a flag. Also you don't need to run the inner loop i times, infact only i/2 times is sufficient. This is simple mathematics, but will save significant number of CPU cycles (~5000 iterations lesser in your case)
#include <iostream>
int main()
{
int n = 10;
for(int i=2; i<=n; i++){
bool isPrime = true;
for(int j=2; j<=i/2; j++){
if(i!=j && i%j==0){
isPrime = false;
break;
}
}
if(isPrime)
std::cout << i << " ";
}
return 0;
}

Another version, if you don't mind output in reverse order.
int n = 10;
for (int i = n; i > 1; --i)
{
int factorCount = 0;
for (int j = 2; j <= n; ++j)
{
if (i % j == 0)
factorCount++;
if (factorCount > 1)
break;
}
if (factorCount == 1)
cout << i << endl;
}

int main() {
for (int i = 2; i <= 100; i++) {
for (int j = 2; j < i; j++) {
if (i%j == 0)
break;
if (j==i-1) // means has never run previous if blog
cout << i << endl;
}
}
return 0;
}

Related

Can I create a for loop with two variables and still have time complexity of O(n)?

Say I have a for loop as:
for(int i=0,j=i+1;i<n-1,j<n;j++)
{
//some code
if(condition)
{
i++;
j=i;
}
}
What will be the time complexity and why?
Edited:
void printAllAPTriplets(int arr[], int n)
{
for (int i = 1; i < n - 1; i++)
{
// Search other two elements of
// AP with arr[i] as middle.
for (int j = i - 1, k = i + 1; j >= 0 && k < n;)
{
// if a triplet is found
if (arr[j] + arr[k] == 2 * arr[i])
{
cout << arr[j] << " " << arr[i]
<< " " << arr[k] << endl;
// Since elements are distinct,
// arr[k] and arr[j] cannot form
// any more triplets with arr[i]
k++;
j--;
}
// If middle element is more move to
// higher side, else move lower side.
else if (arr[j] + arr[k] < 2 * arr[i])
k++;
else
j--;
}
}
}
What would be the time complexity of this particular function and why?? #walnut #DeducibleSteak #Acorn .This is the code for "Printing all triplets in sorted array that form AP"
O(n^2) is when you iterate through all the possible values of one variable each time you iterate through the second one. As such:
for(int i=0; i < n; i++){
for (int j = 0; j < m; j++{
//Do some action
}
}
In your example, even though you're using two vars, but it's still a O(n).
Assuming that increasing i by one takes one second, then assigning the new i to j takes one second too, then the complexity is O(2n). Since constant numbers are insignificant when speaking about complexities, then the complexity of your code is still O(n)
The loop you have written does not make sense, because you are using the comma operator and discarding one of the conditions, so it is equivalent to j < n.
Even if the condition gets triggered many times (but a constant number w.r.t. n, i.e. not becoming larger as n grows), then you can easily show you will do <= k*n iterations, which means O(n) iterations.
If that is not true, but the condition is at least side-effect free, then you can only bound it by O(n^2), e.g. as #walnut suggests with j == n - 1 (like in a triangle matrix).
If you allow for side-effects in the condition (e.g. j = 0, with an equals sign), then it can be an infinite loop, so there is no possible bound.

Issues with Sieve of Eratosthenes

I picked up "Programming Principles and Practice using C++", and was doing an early problem involving the Sieve of Eratosthenes, and I'm having unexpected output, but I cannot pin down exactly what the problem is. Here is my code:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> prime;
std::vector<int> nonPrime;
int multiple = 0;
for(int i = 2; i < 101; i++) //initialized to first prime number, i will
// be the variable that should contain prime numbers
{
for(int j = 0; j < nonPrime.size(); j++) //checks i against
// vector to see if
// marked as nonPrime
{
if(i == nonPrime[j])
{
goto outer;//jumps to next iteration if number
// is on the list
}
}
prime.push_back(i); //adds value of i to Prime vector if it
//passes test
for(int j = i; multiple < 101; j++) //This loop is where the
// sieve bit comes in
{
multiple = i * j;
nonPrime.push_back(multiple);
}
outer:
;
}
for(int i = 0; i < prime.size(); i++)
{
std::cout << prime[i] << std::endl;
}
return 0;
}
The question only currently asks me to find prime numbers up to 100 utilizing this method. I also tried using this current 'goto' method of skipping out of a double loop under certain conditions, and I also tried using a Boolean flag with an if statement right after the check loop and simply used the "continue;" statement and neither had any effect.
(Honestly I figured since people say goto was evil perhaps it had consequences that I hadn't foreseen, which is why I tried to switch it out) but the problem doesn't call for me to use modular functions, so I assume it wants me to solve it all in main, ergo my problem of utilizing nested loops in main. Oh, and to further specify my output issues, it seems like it only adds multiples of 2 to the nonPrime vector, but everything else checks out as passing the test (e.g 9).
Can someone help me understand where I went wrong?
Given that this is not a good way to implement a Sieve of Eratosthenes, I'll point out some changes to your code to make it at least output the correct sequence.
Please also note that the indentation you choose is a bit misleading, after the first inner loop.
#include <iostream>
#include <vector>
int main()
{
std::vector<int> prime;
std::vector<int> nonPrime;
int multiple = 0;
for(int i = 2; i < 101; i++)
{
// you can use a flag, but note that usually it could be more
// efficiently implemented with a vector of bools. Try it yourself
bool is_prime = true;
for(int j = 0; j < nonPrime.size(); j++)
{
if(i == nonPrime[j])
{
is_prime = false;
break;
}
}
if ( is_prime )
{
prime.push_back(i);
// You tested 'multiple' before initializing it for every
// new prime value
for(multiple = i; multiple < 101; multiple += i)
{
nonPrime.push_back(multiple);
}
}
}
for(int i = 0; i < prime.size(); i++)
{
std::cout << prime[i] << std::endl;
}
return 0;
}

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

C++ Prime number task from the book

I'm a C++ beginner ;)
How good is the code below as a way of finding all prime numbers between 2-1000:
int i, j;
for (i=2; i<1000; i++) {
for (j=2; j<=(i/j); j++) {
if (! (i%j))
break;
if (j > (i/j))
cout << i << " is prime\n";
}
}
You stop when j = i.
A first simple optimization is to stop when j = sqrt(i) (since there can be no factors of a number greater than its square root).
A much faster implementation is for example the sieve of eratosthenes.
Edit: the code looks somewhat mysterious, so here's how it works:
The terminating condition on the inner for is i/j, equivalent to j<i (which is much clearer),since when finally have j==i, we'll have i/j==0 and the for will break.
The next check if(j>(i/j)) is really nasty. Basically it just checks whether the loop hit the for's end condition (therefore we have a prime) or if we hit the explicit break (no prime). If we hit the for's end, then j==i+1 (think about it) => i/j==0 => it's a prime. If we hit a break, it means j is a factor of i,but not just any factor, the smallest in fact (since we exit at the first j that divides i)!
Since j is the smallest factor,the other factor (or product of remaining factors, given by i/j) will be greater or equal to j, hence the test. If j<=i/j,we hit a break and j is the smallest factor of i.
That's some unreadable code!
Not very good. In my humble opinion, the indentation and spacing is hideous (no offense). To clean it up some:
int i, j;
for (i=2; i<1000; i++) {
for (j=2; i/j; j++) {
if (!(i % j))
break;
if (j > i/j)
cout << i << " is prime\n";
}
}
This reveals a bug: the if (j > i/j) ... needs to be on the outside of the inner loop for this to work. Also, I think that the i/j condition is more confusing (not to mention slower) than just saying j < i (or even nothing, because once j reaches i, i % j will be 0). After these changes, we have:
int i, j;
for (i=2; i<1000; i++) {
for (j=2; j < i; j++) {
if (!(i % j))
break;
}
if (j > i/j)
cout << i << " is prime\n";
}
This works. However, the j > i/j confuses the heck out of me. I can't even figure out why it works (I suppose I could figure it out if I spent a while looking like this guy). I would write if (j == i) instead.
What you have implemented here is called trial division. A better algorithm is the Sieve of Eratosthenes, as posted in another answer. A couple things to check if you implement a Sieve of Eratosthenes:
It should work.
It shouldn't use division or modulus. Not that these are "bad" (granted, they tend to be an order of magnitude slower than addition, subtraction, negation, etc.), but they aren't needed, and if they're present, it probably means the implementation isn't really that efficient.
It should be able to compute the primes less than 10,000,000 in about a second (depending on your hardware, compiler, etc.).
First off, your code is both short and correct, which is very good for at beginner. ;-)
This is what I would do to improve the code:
1) Define the variables inside the loops, so they don't get confused with something else. I would also make the bound a parameter or a constant.
#define MAX 1000
for(int i=2;i<MAX;i++){
for(int j=2;j<i/j;j++){
if(!(i%j)) break;
if(j>(i/j)) cout<<i<<" is prime\n";
}
}
2) I would use the Sieve of Eratosthenes, as Joey Adams and Mau have suggested. Notice how I don't have to write the bound twice, so the two usages will always be identical.
#define MAX 1000
bool prime[MAX];
memset(prime, sizeof(prime), true);
for(int i=4;i<MAX;i+=2) prime[i] = false;
prime[1] = false;
cout<<2<<" is prime\n";
for(int i=3;i*i<MAX;i+=2)
if (prime[i]) {
cout<<i<<" is prime\n";
for(int j=i*i;j<MAX;j+=i)
prime[j] = false;
}
The bounds are also worth noting. i*i<MAX is a lot faster than j > i/j and you also don't need to mark any numbers < i*i, because they will already have been marked, if they are composite. The most important thing is the time complexity though.
3) If you really want to make this algorithm fast, you need to cache optimize it. The idea is to first find all the primes < sqrt(MAX) and then use them to find the rest of the
primes. Then you can use the same block of memory to find all primes from 1024-2047, say,
and then 2048-3071. This means that everything will be kept in L1-cache. I once measured a ~12 time speedup by using this optimization on the Sieve of Eratosthenes.
You can also cut the space usage in half by not storing the even numbers, which means that
you don't have to perform the calculations to begin working on a new block as often.
If you are a beginner you should probably just forget about the cache for the moment though.
The one simple answer to the whole bunch of text we posted up here is : Trial division!
If someone mentioned mathematical basis that this task was based on, we'd save plenty of time ;)
#include <stdio.h>
#define N 1000
int main()
{
bool primes[N];
for(int i = 0 ; i < N ; i++) primes[i] = false;
primes[2] = true;
for(int i = 3 ; i < N ; i+=2) { // Check only odd integers
bool isPrime = true;
for(int j = i/2 ; j > 2 ; j-=2) { // Check only from largest possible multiple of current number
if ( j%2 == 0 ) { j = j-1; } // Check only with previous odd divisors
if(!primes[j]) continue; // Check only with previous prime divisors
if ( i % j == 0 ) {
isPrime = false;
break;
}
}
primes[i] = isPrime;
}
return 0;
}
This is working code. I also included many of the optimizations mentioned by previous posters. If there are any other optimizations that can be done, it would be informative to know.
This function is more efficient to see if a number is prime.
bool isprime(const unsigned long n)
{
if (n<2) return false;
if (n<4) return true;
if (n%2==0) return false;
if (n%3==0) return false;
unsigned long r = (unsigned long) sqrt(n);
r++;
for(unsigned long c=6; c<=r; c+=6)
{
if (n%(c-1)==0) return false;
if (n%(c+1)==0) return false;
}