Prime number nested loop Logic - c++

I am currently working on assignment which is stated below. My question is that why does my code only repeat prime number as 2 and not the remainder of the numbers. I would much appreciate if someone could help me to walk through the logic so i can try to solve the solution, rather than posting the answer outright. Kudos to all :)
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.
(Prime numbers are natural numbers that are not evenly divisible by
any other number except for themselves and one). Display all the
primes found.
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> n; // will store our values from 1-10000
for (int i= 0; i < 10000; i++) { // vector loading
n.push_back(i);
n[i]= n[i] + 1;
for (int j= 1; j < 10000 ; j++ ) { // Error is here?
if (n[j] % j == 0) { // supposed to go through all the numbers
// and flag the prime numbers
cout<<n[i] <<" is a prime";
i++;
break;
}
}
}
return 0;
}

The trivial method is rather easy to understand.
Outer loop (suppose the loop variable here is num) go through from 2 to 10000, and check every number whether it is a prime number.
Inner loop (suppose the loop variable here is fact) go through form 2 to num - 1
Check if num has a factor fact by num % fact == 0. If fact is a factor of num, then break the inner loop and continue to check the next number.
If after checking all the numbers from 2 to num - 1 and none of them is the factor of num, then we are sure that num is a prime number and continue to check the next number.
Note that 0 and 1 are special case so we exclude them from the loop.
This method doesn't need any array. The time complexity is O(n2) and space complexity is O(1).
BTW, there are other better solution to this problem, for example Sieve of Eratosthenes.

There are a couple of problems but for a starter consider the very first loop.
i = 0
n.push_back(i); // Now n[0] is now valid (having the value 0)
n[0] = n[0] + 1; // Now n[0] is still valid (having the value 1)
j = 1;
if (n[j] % j == 0) // Ups... access to n[1] which is invalid
// as you have only pushed one element, i.e. n[0]

Understand the purpose of your loops
The outer loop is the one that supplies the numbers, therefore you
don't need the vector
The inner loop is the one that does the checking
Where do you print?
The inner loop checks if a number is not prime. The only way it
knows this is if the number supplied by the outer loop is not divisible by any number supplied by the inner loop. Therefore the inner loop
does not print anything because it has to exhaust all checks before it knows that a number is prime
Your print statement should come last. This means it should be after the inner loop but still inside the outer loop and it should print the number if it is prime based on what was discovered by the inner loop. So you should have a way of knowing if the inner loop found a prime or not
Finally note that the inner loop has to start at 2 and end at i - 1 because every number is divisible by 1 and itself

Do not need to iterate through the entire range for inner loop, for inner loop there will possible values are starting from 2 to <= that number /2 .
Like if you want to check whether 99 is prime or not then you need to
set inner loop from 2 to 49 (99 / 2 is the max possible factor for
that number) so do not iterate through the rest all.
So if you iterate inner loop from 2 to 98 then it's meaning less to
iterate this loop after 49, think about it.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
//vector<int> n; // will store our values from 1-10000
int flag =0;
for (int i= 2; i < 10000; i++) // vector loading
{
//n.push_back(i);
//n[i]= n[i] + 1;
flag =0;
for (int j= 2; j <= i / 2 ; j++ )
{
if (i % j == 0)
{
flag = 1;
break;
}
}
if(flag == 0)
{
cout << "%d number is Prime" << i;
}
}
return 0;
}

Related

Prime numbers between two given integers

This is my code for finding prime numbers between two integers. It compiles alright but giving a runtime error SIGXFSZ on codechef.
#include <bits/stdc++.h>
using namespace std;
int main() {
long long n,m;
int t;
cin>>t;
while(t--)
{
cin>>m>>n;
for(long long j=m;j<=n;j++)
for(long long i=2;i<=sqrt(j);i++)
if(j%i==0)
break;
else cout<<j<<"\n";
cout<<"\n";
}
return 0;
}
Seems that you are wrong on logic.
According to my understanding, you are supposed to print the prime numbers between two numbers.
But your code has logical errors.
1) Code doesn't consider 2 and 3 as prime numbers.
Say, m = 1, n = 10. For j = 2, 3, the inner loop won't execute even for the single time. Hence, the output won't be shown to be user.
2) else cout<<j<<"\n"; statement is placed incorrectly as it will lead to prime numbers getting printed multiple times and some composite numbers also.
Example:
For j = 11, this code will print 11 twice (for i = 2, 3).
For j = 15, this code will print 15 once (for i = 2) though it is a composite number.
You've underexplained your problem and underwritten your code. Your program takes two separate inputs: first, the number of trials to perform; second, two numbers indicating the start and stop of an individual trial.
Your code logic is incorrect and incomplete. If you were to use braces consistently, this might be clear. The innermost loop needs to fail on non- prime but only it's failure to break signals a prime, so there can't be one unless the loop completes. The location where you declare a prime is incorrect. To properly deal with this situation requires some sort of flag variable or other fix to emulate labelled loops:
int main() {
int trials;
cin >> trials;
while (trials--)
{
long long start, stop;
cin >> start >> stop;
for (long long number = start; number <= stop; number++)
{
if (number < 2 || (number % 2 == 0 && number != 2))
{
continue;
}
bool prime = true;
for (long long odd = 3; odd * odd <= number; odd += 2)
{
if (number % odd == 0)
{
prime = false;
break;
}
}
if (prime)
{
cout << number << "\n";
}
}
}
return 0;
}
The code takes the approach that it's simplest to deal with even numbers and two as a special case and focus on looping over the odd numbers.
This is basically "exceeded file size", which means that the output file is having size larger than the allowed size.
Please do check the output file size of your program.

Comparing Floats in a vector

I am writing a program that creates two vectors to practice comparing elements in a vector. The first vector is a list of all numbers that are not prime numbers between 1-100 (not prime numbers), the second vector is a list of all numbers between 1-100 (vector number_bank). I am using loops to compare each element in the vectors. Lets say the number 5 comes up from the number_bank (which is a prime number), if this number does not match any number in the not_prime_numbers vector then it is pushed back into a third vector called prime numbers. If a number like 4 were to be compared to the elements of the not_prime_number list it is supposed to match with the number 4 in this list and break the loop without pushing back the number into the prime_numbers vector. What is happening is all numbers between 1-100 are being pushed back. 4 in the number_bank vector is never equal to the 4 in the not_prime_numbers vector so the cycle continues pushing back 4 into the prime numbers vector.
There is no math involved changing the elements in these vectors so there shouldn't be an incremental margin of error (epsilon) usually associated with comparing floats. Is there a better way to compare the elements in these vectors?
int main()
{
float i = 1.0;
unsigned int n = 0;
std::vector<float>not_prime_numbers;
std::vector<float>number_bank;
std::vector<float>prime_numbers;
while (i < 101.0)
{
for (float j = 1.0;j<(i);++j)
{
float p = i / j;
if (abs(floor(p)) == p&&j!=1.0)
{
not_prime_numbers.push_back(i);
break;
}
}
++i;
}
for (float k = 1.0; k < 101.0; ++k)
{
number_bank.push_back(k);
}
for (unsigned int m = 0; m < number_bank.size(); ++m)
{
while (n < not_prime_numbers.size())
{
if (not_prime_numbers[n] == number_bank[m]) // here is where i try to break the loop
{
break;
}
if (n == (not_prime_numbers.size()-1))
{ // here is where element is pushed back when compared to all loop elements
prime_numbers.push_back(number_bank[m]);
break;
}
if (not_prime_numbers[n] != number_bank[m])
{
++n;
}
}
}
std::cout << "All prime numbers between 0 and 100 are as follows:\n";
for (unsigned int j = 0; j < prime_numbers.size(); ++j)
{
std::cout << prime_numbers[j] << "\n";
}
return 0;
}
I read about .compare and tried it but it states that there needs to be a class structure to the left (perhaps a vector has no class structure?). I'm new to C++ and would greatly appreciate the help.
You never reset n, so once you get a prime number (when n == (not_prime_numbers.size()-1)) the rest of the numbers will also be added to the prime list.
Why are you checking that condition within the loop? You should set a flag variable if you find the number is not prime, then check that after your loop to possibly add it to your prime list.

Reversing positive sequences in array

So, I have a cycle that goes over an array and should reverse the sequence of consecutive positive numbers, but it seems to count excess negative number as a part of a sequence, thus changing its position. I can't figure the error myself, and will be happy to hear any tips!
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
int Arr[100];
int Arr2[100];
int main()
{
srand(time(NULL));
int n, x;
bool seq = false;
int ib = 0;
printf("Starting array\n");
for (n = 0; n < 100; Arr[n++] = (rand() % 101) - 50);
for (n = 0; n < 100; printf("%3d ", Arr[n++]));
putchar('\n');
for (n = 0; n < 100; n++) //sorting
{
if (Arr[n] > 0) //check if the number is positive
{
if (seq == false) //if it isn't the part of a sequence
{
seq = true; ib = n; //declare it now is, and remember index of sequence's beginning
}
else
seq = true; //do nothing if it isn't first
}
else //if the number is negative
{
if (seq==true) //if sequence isn't null
for (x = n; ib <= n; ib++, x--) //new variable so that n will stay unchanged,
number of iterations = length of sequence
{
Arr2[x] = Arr[ib]; //assigning array's value to a new one,
reversing it in the process
}
seq = false; //declaring sequence's end
Arr2[n + 1] = Arr[n + 1]; //assigning negative numbers at the same place of a new array
}
}
printf("Modified array\n");
for (n = 0; n < 100; printf("%3d ", Arr2[n++]));
putchar('\n');
system('pause');
return 0;
}
following what we discussed in comments, i listed couple of rules here to shape my answer around it.
Rules :
the sequence of elements can be varied. so if there are 5 positive numbers in a row within an array, we would be reversing the 5 elements. for example
array[5] = {1,2,3,4,5} would become array[5]{5,4,3,2,1}
if single positive number neighboured by negatives, no reverse can happen
array[4] = {-1,0,-2,1} would result the same array
no processing happens when a negative number is discovered.
based on these rules.
here is what I think going wrong in your code.
Problems :
1- consider thisarray = {1,2,-1}. notice that the last value is negative. because of this. the following code would run when the 3rd index of the array is processed;
` Arr2[n + 1] = Arr[n + 1]; //assigning negative numbers at the same place of a new array`
this is a no-no. since you are already at the end of the Arr2 n+1 would indicate that there is a 4th element in the array. (in your case 101h element of the array) this would cause an undefined behaviour.
2 - consider the same array mentioned above. when that array is looped, the outcome would be array = {-1,2,1} . the -1 and 1 are swapped instead of 1 and 2.
3 - you are assigning ib = n whenever a negative number is found. because whenever a negative value is hit, seq=false is forced. But the ib, never been put into use until a next negative number is found. here is an example;
array = {...2, 6}
in such scenario, 2 and 6 would never get reversed because there is no negative value is following this positive sequence.
4 - consider this scenario arr = {-10,-1,....} this would result in arr = {0,-1,....}. This happens because of the same code causing the undefined behaviour problem mentioned above.
`Arr2[n + 1] = Arr[n + 1];`
Suggestion
Most of the problems mentioned above is happening because you are trying to figure out the sequence of the positive numbers when a negative number is found.
else //if the number is negative
{
if (seq==true) //if sequence isn't null
for (x = n; ib <= n; ib++, x--) //new variable so that n will stay unchanged,
number of iterations = length of sequence
{
Arr2[x] = Arr[ib]; //assigning array's value to a new one,
reversing it in the process
}
you should completely get rid of that and completely ignore the negative numbers unless you forgot to mention in your question some key details. instead just focus on the positive numbers. I'm not going to send you the entire code but here is how I approached the problem. feel free to let me know if you need help and I would be more then happy to go through in detail.
start your for loop as usual.
for (n = 0; n < 100; n++) //sorting
{
don't try to do anything when an element in an array is a negative value.
if (Arr[n] > 0) //check if the number is positive
if the number is positive. create recording the sequence indices. for one, we know the sequence will start at n once the `if (Arr[n] > 0) true. so we can do something like this;
int sequenceStart = n;
we also need to know when the positive number sequence ends.
int sequenceEnd = sequenceStart;
the reason for int sequenceEnd = sequenceStart; is because we going to start using the same n value to start with. we can now loop through the array and increment the sequenceEnd until we reach to a negative number or to the end of the array.
while (currentElement > 0)
{
n++;//increment n
if(n < arraySiz) //make sure we still in the range
{
currentElement = Arr[n]; // get the new elemnet
if (currentElement > 0)
{
sequenceEnd++;
}
}
else
break; // we hit to a negative value so stop the while loop.
}
notice the n++;//increment n this would increment the n++ until we reach to the negative number. which is great because at the end of the sequence the for loop will continue from the updated n
after the while loop, you can create an array that has the same size as the number of sequences you iterated through. you can then store the elements from starting arr[sequenceStart] and arr[sequenceEnd] this will make the reversing the sequence in the array easier.

basic nestled loop calculate prime numbers between 1 - 239, inclusive

I am working on a program in which I must print out the number of primes, including 1 and 239, from 1 - 239 ( I know one and or two may not be prime numbers, but we will consider them as such for this program) It must be a pretty simple program because we have only gone over some basics. So far my code is as such, which seems like decent logical flow to me, but doesnt produce output.
#include <iostream>
using namespace std;
int main()
{
int x;
int n = 1;
int y = 1;
int i = 0;
while (n<=239)
{x = n % y;
if (x = 0)
i++;
if (y < n)
y++;
n++;
while (i == 2)
cout << n;
}
return 0;
}
The way I want this to work is to take n, as long as n is 239 or less, and preform modulus division with every number from 1 leading up to n. Every time a number y goes evenly into n, a counter will be increased by 1. if the counter is equal to 2, then the number is prime and we print it to the screen. Any help would be so greatly appreciated. Thanks
std::cout << std::to_string(2) << std::endl;
for (unsigned int i = 3; i<240; i += 2) {
unsigned int j = 3;
int sq = sqrt(i);
for (; j <= sq; j += 2) if (!(i%j)) break;
if (j>sq) std::cout << std::to_string(i) << std::endl;
}
first of all, the prime definition: A prime number (or a prime) is a natural number greater than 1 that has no positive divisors other than 1 and itself.
so you can skip all the even numbers (and hence ... i+=2).
Moreover no point to try to divide for a number greater than sqrt(i), because then it will have a divisor less than sqrt(i) and the code finds that and move to the next number.
Considering only odd numbers, means that we can skip even numbers as divisors (hence ... j+=2).
In your code there are clearly beginner errors, like (x = 0) instead of x==0. but also the logic doesn't convince. I agree with #NathanOliver, you need to learn to use a debugger to find all the errors. For the rest, good luck with the studies.
lets start with common errors:
first you want to take input from user using cin
cin>>n; // write it before starting your while loop
then,
if (x = 0)
should be:
if (x == 0)
change your second while loop to:
while (i == 2){
cout << n;
i++;
}

determining time complexity

I was reading a book which tells that the outer loops time complexity is O(n-m) whereas for inner loop the books gives explanation as
" The inner while loop goes around at most m times, and potentially
far less when the pattern match fails. This, plus two other
statements, lies within the outer for loop. The outer loop goes around
at most n−m times, since no complete alignment is possible once we get
too far to the right of the text. The time complexity of nested loops
multiplies, so this gives a worst-case running time of O((n − m)(m +
2)). "
I didn't understand for what reason the time complexity of inner loop is O(m+2) instead of O(m)? Please help.
int findmatch(char *p, char *t)
{
int i,j; /* counters */
int m, n; /* string lengths */
m = strlen(p);
n = strlen(t);
for (i=0; i<=(n-m); i=i+1) {
j=0;
while ((j<m) && (t[i+j]==p[j]))
j = j+1;
if (j == m) return(i);
}
return(-1);
}
The while loop:
while ((j<m) && (t[i+j]==p[j]))
j = j+1;
is O(m), then you have +2 from (other statements):
j=0; // + 1
// loop
if (j == m) return(i); // + 1