I am trying, to write a program in C++, that will calculate prime numbers, and store them in an array. Consider this is my third code.
The problem I have run into, is that, while I get Prime numbers, I also get composite numbers, specifically multiples of 5 and 7 (at least until the limit of 30). I know, the code will probably, be terrible, but it was, what I could come up with given my limited experience in both coding and prime numbers.
This is what I've written:
#include <iostream>
int j;
int i = 3;
int prime[30];
int main()
{
for (i; i < 30; i+=2)
{
for (j =i; j>i*i; j--)
{
if ((i % j) == 0)
{
continue;
}
}
prime[i] = i;
std::cout << prime[i] << std::endl;
}
}
output: 3 5 7 9 11 13 15 17 19 21 23 25 27 29
Your inner loop only needs to test divisibility with the prime numbers you've encountered thus far. (e.g. no point in testing divisibility with 9 if you've already tested divisibility with 3)
int main()
{
int j;
int i = 3;
int primes[30];
int primecount = 0;
primes[primecount++] = 2; // hardcode 2, it's the only even number
for (i = 3; i < 30; i += 2)
{
bool isPrime = true;
for (j = 0; j < primecount; j++)
{
if ((i % primes[j]) == 0)
{
isPrime = false;
break;
}
}
if (isPrime)
{
primes[primecount++] = i;
}
}
for (int k = 0; k < primecount; k++)
{
std::cout << primes[k] << " ";
}
std::cout << std::endl;
}
As CoderCharmander points out in the comments, that continue only breaks from the inner loop but you intended to continue with the outer loop. Smallest fix is to use the dreaded goto, entirely appropriate here.
Also the inner for loop specification is all wrong:
#include <iostream>
int prime[30];
int main()
{
int i, j;
std::cout << 2 << " "; // the first prime is 2
for (i=3; i < 30; i+=2)
{
for // all wrong: (j =i; j>i*i; j--)
(j = 2; j*j <= i; ++j) // or even, (j = 3; j*j <= i; j += 2)
{
if ((i % j) == 0)
{
prime[i] = 0; // initialize the non-primes as well!
goto L1; // continue the outer loop
}
}
// the inner loop finished normally
prime[i] = i;
std::cout << i << " ";
L1: ;
}
}
This also needlessly tests the numbers by all the numbers above 2 smaller than the threshold (or by the odds, as in the commented suggestion) but we only really need to test by primes.
When making this amendment it's important to be careful not to introduce the much bigger inefficiency than the one we were trying to fix (a quadratic loss in time complexity over an intended log factor gain), as there's no point in testing divisibility of e.g. 23 by 5,7,11,13 and 19.
And actually testing divisibility can be avoided altogether, if one so chooses, but that's another matter entirely.
Related
I'm coding on a leetcode-like platform. There is a task: counter the number of primes below a given bound.
I used the algorithm: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
I copy the code from here: https://www.geeksforgeeks.org/sieve-of-eratosthenes/ , except that I make false represents isPrime to avoid using memset. Here is my code:
void SieveOfEratosthenes(int n)
{
bool *prime = new bool[n+1](); // initialized by false by default
for (int p=2; p*p<=n; p++)
{
if (prime[p] == false)
{
for (int i=p*p; i<=n; i += p)
prime[i] = true;
}
}
for (int p=2; p<=n; p++)
if (prime[p])
cout << p << " ";
}
However, when I execute it, the platform tells me that I used too much memory in the case of 100 000 000 as the enter.
I've checked that sizeof(bool) equals to 1.
Is there some way to use less memory for this piece of code?
A couple of suggestions:
use a bit array representing only odd numbers
break the problem up into segments so the partial sieve uses much less memory
#Kim Walish has a fast C++ version here:
https://github.com/kimwalisch/primesieve/wiki/Segmented-sieve-of-Eratosthenes
You can make it use less memory still by always limiting the segment size to the L1 cache size, and by changing the IsPrime array to also be a bit array of odd numbers.
This is a memory optimized implementation of the sieve of eratosthenes. The basic idea is that, you only need to store the status of the odd numbers. Rest of it is similar to the normal implementation.
#include <iostream>
class Solution {
public:
int countPrimes(int n) {
//if(n <= 1) return 0; // including n
if(n <= 2) return 0; // number of primes less than 0 / 1 / 2 is 0
const int MAXN = 1500000 + 5; // adjust MAXN accordingly
// finding prime from 1 up to N
int status[(MAXN >> 1) + 1]; // we need space for only the odd numbers
// works well up to 1.5 * 10 ^ 6, for numbers larger than that, you need to adjust the second operand accordingly
int prime[115000 + 1000]; // prime number distribution , pi(x) = x/ (ln(x) - 1) , adjust this according to MAXN
// If status[i] = 0 -> i is prime
// If status[i] = 1 -> i is not prime
for(int i = 1 ; i <= (n >> 1) ; ++i) status[i] = 0; // for every i , 2 * i + 1 is the odd number, marking it as prime
int sqrtN = static_cast <int> ((sqrt (static_cast <double> (n))));
// computing sqrt(N) only once because it is costly computing it inside a loop
// only accounting the odd numbers and their multiples
for(int i = 3 ; i <= sqrtN ; i += 2){
if(status[i >> 1] == 0){
// if this is still a prime then discard its multiples
// first multiple that needs to be discarded starts at i * i
// all the previous ones have already been discarded
for(int j = i * i ; j <= n ; j += (i + i)) {
//printf("Marking %d as not prime\n",j);
status[j >> 1] = 1;
}
}
}
int counter = 0;
prime[counter++] = 2;
for(int i = 3 ; i <= n ; i += 2){
if(status[i >> 1] == 0){
prime[counter++] = i;
}
}
if( (n & 1) && !status[n >> 1]) counter--; // if n is prime, discard n
std::cout << "Number of primes less than " << n << " is " << counter << "\n";
for(int i = 0 ; i < counter; ++i){
std::cout << prime[i];
if(i != counter - 1) std::cout << "\n";
}
std::cout << "\n";
return counter;
}
};
int main(int argc, char const *argv[])
{
Solution solution;
int n; std::cin >> n;
solution.countPrimes(n);
return 0;
}
I am currently working on a program that finds prime numbers, I know there are less convoluted ways to find prime numbers but I'm trying to practice comparing elements in vectors (not_prime_numbers & number bank(numbers from 1-100)) and when a value that is a prime number is found it is put into the final prime_number vector.
I am using loops to compare elements inside the vectors. When I ask the program to display the vector not_prime_numbers this is not a problem, nor number bank, however when I ask it to display the prime_number vector I get the error vector subscript out of range. Why are the vector elements in prime numbers I am asking to display out of range however using the same loop method to display the elements of vectors not_prime_numbers & number_bank work. Is it a problem with how I compared the two vectors to put the element into a third vector (prime_numbers)?
#include "pch.h"
#include <iostream>
#include<vector>
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 <= 100.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 <= 100.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])
{
break;
}
if (n == m)
{
prime_numbers.push_back(number_bank[m]);
}
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";
}
}
This is not homework, just personal practice. Any help would be greatly appreciated.
in
while (n <= not_prime_numbers.size())
{
if (not_prime_numbers[n] == number_bank[m])
you go after the last element, test must be n < not_prime_numbers.size()
and same error when you print the result :
for (unsigned int j = 0; j <= prime_numbers.size(); ++j)
{
std::cout << prime_numbers[j] << "\n";
}
must be
for (unsigned int j = 0; j < prime_numbers.size(); ++j)
{
std::cout << prime_numbers[j] << "\n";
}
If valgrind is available on your host, use it to find that kind of errors and lot more
I am trying to teach myself C++ in preparation for graduate school this coming fall but I am having some trouble with this birthday paradox problem. My code seems to run ok but I am not getting the correct output. If anyone has any suggestions please let me know.
#include <cstdlib>
#include <iostream>
#include <ctime>
using namespace std;
int main()
{
srand(time(NULL));
const int trials = 100000;
int birthdays[50];
int numMatches;
for(int i = 2; i <= 50; i++)
{
numMatches = 0;
for(int j = 1; j <= trials; j++)
{
for(int k = 1; k <= i; k++)
{
birthdays[k] = (rand() % 365) + 1;
}
int m = 1;
bool matched = false;
while(m < i && !matched){
int n = m + 1;
while(n <= i && !matched){
if(birthdays[m] == birthdays[n]){
numMatches++;
matched = true;
}
n++;
}
m++;
}
}
cout << "Probability of " << i << " people in a room sharing a birthday is \t"
<< ( float(numMatches) / float(trials) ) << endl;
}
}
Your code is not computing the probability of two people in a room of 50 sharing a birthday. There's several bugs, mostly with indexing, but here's the biggest issue:
for(int j = 1; j <= trials; j++) {
// assigns a random birthday to the first i people (should be 0 indexed)
for(k = 1; k <= i; k++)
birthdays[k] = (rand() % 365) + 1;
// Does *exactly* the same thing as the previous loop, overwriting what
// the initial loop did. Useless code
for(m = 1; m <= i; m++)
birthdays[m] = (rand() % 365) + 1;
// At this point, m = k = i + 1. Here you check if
// the i + 1st array value has the same b-day. It will, because they're
// the same thing. Note you never set the i + 1st value so the loops
// above did nothing
if(birthdays[k] == birthdays[m])
++numMatches;
}
So what you've got here is something like:
Perform 48 iterations of the following (from your first loop which goes from 2 to 50: no idea where those values came from)
For each of those 48 iterations, perform 10k iterations of:
assign a bunch of random stuff to an array overwriting stuff
Ignore the values you wrote in the array, do a comparison that's always true and increment numMatches by 1
Consider what's going on here:
for(int j = 1; j <= trials; j++) {
for(k = 1; k <= i; k++)
birthdays[k] = (rand() % 365) + 1;
for(m = 1; m <= i; m++)
birthdays[m] = (rand() % 365) + 1;
if(birthdays[k] == birthdays[m])
++numMatches;
}
You go through i birthdays and assign a random number, then you go through the same i birthdays and assign them a new random number. Then you try to find a match for just one value of k and m (which both happen to equal i+1, which isn't one of the values set!).
My suggestion is to break the problem down into smaller units that will make it easier to figure out how to code - here are the functions I would try to write.
/* randomizeBirthdays()
* Put n random birthdays into the pre-allocated array birthdays.
* birthdays must of course be of length <= n.
*/
void randomizeBirthdays(int * birthdays, int n);
/* hasMatchingBirthdays()
* Check if birthdays array has two people with the same birthday
* in the first n entries.
* Return value is boolean.
*/
bool hasMatchingBirthdays(int * const birthdays, int n);
/* probabilityOfMatch()
* Calculate the probability that at least 2 out of n people will
* have the same birthday, using nTrials number of trials.
* Return value is double.
*/
double probabilityOfMatch(int n, int nTrials);
If you break it down like this it becomes easier to write and easier to troubleshoot.
As I said in comments already:
I think your aim is to test if 2 people in room of 2-50 people share
birthday, not if 2-50 people share birthday as you say in output. And
that's 2 people out of 23 have 50.7%, not 24.
I completely reworked your code:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
#define DAYS_IN_YEAR 365
#define TRIALS 10000
void clearArray (bool * array)
{
for (int i = 0; i < DAYS_IN_YEAR; i++)
array[i] = false;
}
int main()
{
srand(time(NULL));
bool birthdays[DAYS_IN_YEAR]; //we are trying to hit same day in year twice
int r, numMatches;
for(int i = 2; i < 50; i++)
{
numMatches = 0;
for(int j = 0; j < TRIALS; j++)
{
clearArray(birthdays);
for(int k = 0; k < i; k++)
{
r = rand() % DAYS_IN_YEAR; // == 0-364
if (birthdays[r])
{
numMatches++;
break; // 2 people already have same birthdays here
}
birthdays[r] = true;
}
}
cout << "Probability of 2 people having same birthday in room of " << i << " people is "
<< (float)numMatches / TRIALS << endl;
}
}
Output:
Probability of 2 people having same birthday in room of 23 people is 0.516
I think the code must be something like this.
#include <cstdlib>
#include <iostream>
#include <ctime>
using namespace std;
int main() {
srand(time(NULL));
int birthdays[10000][50];
int numMatches;
int trials=10000,check;
for(int n=0;n<trials;n++)
{
for(int j=0;j<50;j++)
{
birthdays[n][j]=rand()%365+1;
}
}
for(int i=2;i<=50;i++)
{
numMatches=0;
for(int n=0;n<trials;n++)
{
check=1;
for(int j=0;j<i;j++)
{
for(int k=j+1;k<=i;k++)
{
if(birthdays[n][j]==birthdays[n][k]&&check)
{
numMatches++;
check=0;
}
}
}
}
cout << "Probability of " << i << " people in a room sharing a birthday is \t" <<
(static_cast<float>(numMatches) / (trials)) << endl;
}
}
Okay, so I'm a complete noob. I'm trying my hand at Project Euler to get better at C++. I'm doing problem #1, but I'm not getting the correct output. When I run it, I get that numTotalThree is -3, and numTotalFive is -5, and that numTotal is 0. There's something wrong with my functions, but I'm not sure what I've done wrong. How do I fix this?
#include <iostream>
using namespace std;
int main()
{
int amount = 1000;
int numOfThree = amount / 3;
int numOfFive = amount / 5;
int numTotalThree = 0;
int numTotalFive = 0;
int numTotal = numTotalThree + numTotalFive;
cout << numOfThree << endl;
cout << numOfFive << endl;
for(int i = 0; i <= numOfThree; i++)
{
numTotalThree += numTotalThree + 3;
}
cout << numTotalThree << endl;
for(int i = 0; i <= numOfFive; i++)
{
numTotalFive += numTotalFive + 5;
}
cout << numTotalFive << endl;
cout << numTotal << endl;
system("PAUSE");
return 0;
}
I guess you need something like this:
int sum = 0;
for (int i =0; i < 1000; ++i){
if(i % 3 == 0 || i % 5 == 0){
sum += i;
}
}
Later edit: I don't know why you want to count the numbers divisible with 3 or 5 that are less than 1000. The problem (Project Euler - Problem 1) asks for the sum of all the numbers less than 1000, divisible with 3 or 5.
C++ is not a functional language it's procedural - that means you have to do things in order. When you do this:
int numTotalFive = 0;
int numTotal = numTotalThree + numTotalFive;
It will be executed then and there and not again when numTotalThree and numTotalFive are updated. If you don't touch it again that's the value that will be output.
Here's an idea to go on:
Check how many are divisible by three by checking that the remainder %==0. Do the same for five, and then for both of them. Subtract from the total of the first two the number that is divisible by both to get an accurate answer.
int divisibleByThree=0;
int divisibleByFive=0;
int divisibleByBoth=0;
int total;
for(int i=0; i<1000; i++)
{
if (i%3==0)
divisibleByThree++;
if (i%5==0)
divisibleByFive++;
if (i%5==0) && i%5==0)
divisibleByBoth++;
}
total = divisibleByThree + divisibleByFive - divisibleByBoth;
return total;
Your
numTotalThree is overflowing for n in [0, 333]
3/2*(-2 + 2n)
Similarly numTotalFive for n in [0, 200]
5/2*(-2 + 2n)
So you're seeing negative values.
As other suggested you probably need to revisit your logic.
All you need is just to sum up the numbers in [0,1000] that are divisible by 3 or 5
size_t total =0;
for (size_t x =0; x < 1000; x++){
if( (x % 3 == 0) || (x % 5 == 0) ){
total += x;
}
}
So the point is to have the program find and list all prime numbers between 1 and the number you enter. I'm using number_test as the number tested for prime, and divisor and the number to divide by.
I'm not sure what's wrong, as to me it looks functionally the same as the program posted here: Printing prime numbers from 1 through 100
with some minor changes (inputting a number, changing "i" to less than the number entered).
I've been looking for the past three or four days, and I haven't found anything that really answers this question fully, to the degree I need for class. Any help is much appreciated.
#include iostream
#include conio.h
using namespace std;
void main(void){
//Declare variables
int number_entered;
//Get inputs
cout << "This program lists all prime numbers from 1 through a positive number entered."
<< endl;
cout << "Please enter a positive integer."
<< endl;
cin >> number_entered;
cout << "Displaying all numbers from 1 to " << number_entered
<< endl
<< "Press any key to continue..."
<< endl;
getch();
for(int number_test = 2; number_test < number_entered; number_test++){
for(int divisor = 2; divisor < number_test; divisor++){
if(number_test % divisor == 0){
break;
}
else if(number_test % divisor != 0){
cout << number_test << " ";
break;
}
}
}
getch();
}
You should use the Sieve of Eratosthenes to compute the primes less than n. Begin by making a list of all numbers from 2 to the maximum desired prime n. Then, at each iterative step, the smallest remaining number that hasn't yet been considered is output and all of its multiples are crossed off the list.
function primes(n)
sieve := makeArray(2..n, True)
for p from 2 to n step 1
if sieve(p)
output p
for i from p*p to n step p
sieve[i] := False
This O(n log log n) algorithm is very fast; you should be able to compute the 78498 primes less than a million in less than a second.
A simple C++ Program to find the "N" prime numbers.
#include <iostream >
using namespace std;
int main()
{
int N;
cin >> N;
for (int i = 2; N > 0; ++i)
{
bool isPrime = true ;
for (int j = 2; j < i; ++j)
{
if (i % j == 0)
{
isPrime = false ;
break ;
}
}
if (isPrime)
{
--N;
cout << i << "\n";
}
}
return 0;
}
Just a small suggestion. Since prime numbers are odd, even numbers can be left out.
For example, in below loops, i and j increase by 2 (i +=2) instead of by 1 (i ++).
for (int i=3;i<=numberByUser; i+=2){
for (j=3;j<=i;j +=2){
if (i%j==0){
break;
}
}
i think in your answer any way one time the loop will terminated(i am talking about the loop checking the whether it is prime or not)once it comes out you don't know whether it made the break or not.So try to make a flag variable and check outside.I ope that will work
for(n=lower+1; n<upper; n++)
{
prime = 1;
for(i=2; i<n; i++)
if(n%i == 0)
{
prime = 0;
break;
}
if(prime)
printf("\n\n\t\t\t%d", n);
}
for(int number_test = 2; number_test < number_entered; number_test++){
for(int divisor = 2; divisor < number_test; divisor++){
if(number_test % divisor == 0){
break;
}
else if(number_test % divisor != 0){
cout << number_test << " ";
break;
}
}
}
The above code will not show you the prime numbers, it will just show you the number you entered if/when you run into a divisor that is not a factor of the number. For example, if you enter "9", you will start at 2, which is not a factor of 9, so you will show "9" (incorrectly) as a "prime", when it is not.
The easiest method for testing if a number is a prime is by checking all prime numbers below it's square root to see if they are factors of the given number. If none of them are (then none of the non-prime numbers below the given number will be either), the number is a prime number. If it has at least one prime factor less than or equal to it's square root, it is not prime.
Since you are looking to show all primes in a range of [0, X], you can simply check your list of factors as you go along (or do it in reverse, which is effectively what the Sieve of Eratosthenes does).
When my point was like your one, I wrote this code, it worked. Hope it will help you.
#include <cstdio>
#include <vector>
using namespace std;
vector <int> sn;
bool isPrime(int n) {
if (n <= 1) {
return 0;
}
if (n == 2) {
return true;
}
if (!(n % 2)) {
return false;
}
for (int i = 2; i*i <= n; i++) {
if (!(n % i)) {
return 0;
}
}
return 1;
}
void primeNumbers(int k) {
sn.push_back (2);
int i = 3, j = 1;
for ( ; j < k + 1; i += 2 && j++) {
if (isPrime(i)) {
sn.push_back(i);
}
}
}
int main() {
int i, k;
scanf("%d", &k);
primeNumbers(k);
for (i = 0; i < sn.size(); i++) {
printf("%d ", sn[i]);
}
return 0;
}
int getNumberOfPrimes(int N) {
bool *numbers = new bool[N-1]();
for (int i = 2; i <= N/2; ++i) {
if (numbers[i-2] == true) continue;
for (int j = i+i; j <= N; j = j+i) {
numbers[j-2] = true;
}
}
int count = 0;
for (int i = 0; i < (N-1); ++i) {
if (numbers[i] == false) ++count;
}
delete []numbers;
return(count);
}
Man I guess I have the simplest methode of this all. Hope it works for you!
#include < iostream >
using namespace std;
int main()
{
int n, i, j
cin>>n; //The max limith
for(i=2; i<=2; i++)
{
for(j=1; j<=i/2; j++)
if(i%j!=o)
cout<<i;
}
return 0;
}
If a number has divisors, at least one of them must be less than or equal to the square root of the number. When you check divisors, you only need to check up to the square root, not all the way up to the number being tested.