How can I print prime numbers till 10^8 using Sieve? - c++

I have recently learnt Sieve algorithm and started to play with it to learn how to use the algorithm in problems. I have written the code correctly as I can't find any bugs in it, but it closes without showing any output. Can't find what's wrong. Help would be appreciated.
#include <iostream>
#include <vector>
//#define MAX 10000
typedef long long int ll;
using namespace std;
vector <ll> primes;
void sieve(){
ll MAX = 100000000;
bool isPrime [MAX];
for(ll i = 0;i < MAX; ++i)isPrime[i] = true;
//isPrime[0] = isPrime[1] = false;
for(ll i=3; i*i <= MAX; i += 2){
if(isPrime[i]){
for(ll j = i*i; j <= MAX; j += i){
isPrime[j] = false;
}
}
}
primes.push_back(2);
for(ll i = 3; i <= MAX; i += 2){
if(isPrime[i]){
primes.push_back(i);
}
}
for(ll i = 0; i <= 10; ++i){
cout<<primes[i]<<endl;
}
}
int main(){
sieve();
return 0;
}

You are creating a static array of size 10^8, which is stored on the stack. This is too large for the stack, and will likely cause a stack overflow.
Instead, use a vector that stores the data on the heap, like this:
vector<bool> isPrime(MAX+1);
Here's a demo.
Also, note that you have an off by one error, since you are indexing at the index MAX, so the vector should be size MAX+1.
Also, you should avoid using namespace std;, as well as typedefs like ll, they make the code harder to read.

Related

How to find the minimun of an array?

I was trying to solve this question
but codechef.com says the answer is wrong.
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int t, n, diff, mindiff;
cin >> t;
cin >> n;
int val[n];
while(t--)
{
mindiff = 1000000000;
for(int i = 0; i<n; i++)
{
cin >> val[i];
}
int a = 0;
for(a = 0; a<n ; a++)
{
for(int b=a+1; b<n ; b++)
{
diff = abs(val[a] - val[b]);
if(diff <= mindiff)
{
mindiff = diff;
}
}
}
cout << mindiff << endl;
}
return 0;
}
The results are as expected (for at least the tests I did) buts the website says its wrong.
There are a few things in your code that you should change:
Use std::vector<int> and not variable-length arrays (VLA's):
Reasons:
Variable length arrays are not standard C++. A std::vector is standard C++.
Variable length arrays may exhaust stack memory if the number of entries is large. A std::vector gets its memory from the heap, not the stack.
Variable length arrays suffer from the same problem as regular arrays -- going beyond the bounds of the array leads to undefined
behavior. A std::array has an at() function that can check boundary access when desired.
Use the maximum int to get the maximum integer value.
Instead of
mindif = 1000000000;
it should be:
#include <climits>
//...
int mindiff = std::numeric_limits<int>::max();
As to the solution you chose, the comments in the main section about the nested loop should be addressed.
Instead of a nested for loop, you should sort the data first. Thus finding the minimum value between two values is much easier and with less time complexity.
The program can look something like this (using the data provided at the link):
#include <iostream>
#include <vector>
#include <climits>
#include <algorithm>
int main()
{
int n = 5;
std::vector<int> val = {4, 9, 1, 32, 13};
int mindiff = std::numeric_limits<int>::max();
std::sort(val.begin(), val.end());
for(int a = 0; a < n-1 ; a++)
mindiff = std::min(val[a+1] - val[a], mindiff);
std::cout << mindiff;
}
Output:
3
To do this you can use a simple for():
// you already have an array called "arr" which contains some numbers.
int biggestNumber = 0;
for (int i = 0; i < arr.size(); i++) {
if (arr[i] > biggestNumber) {
biggestNumber = arr[i];
}
}
arr.size will get the array's length so that you can check every value from the position 0 to the last one which is arr.size() - 1 (because arrays are 0 based in c++).
Hope this helps.

Strange output with large vectors

I was solving AMR10G problem on spoj. The problem is just about sorting and is trivial to implement with arrays. I'm a beginner in STL and just to get familiar with STL i was trying to solve it with using some vectors. The code runs fine with small sizes of vector but with large sizes( can be 20,000 in the problem) it prints all 0s. Here is my code.
#include <iostream>
#include <vector>
#include <algorithm>
#include <stdio.h>
using namespace std;
int main() {
int T;
cin>>T;
while(T--){
int N, k, i;
cin>>N >> k;
//***********************************************************
vector<int> ar(N);//problem seems to be here when N ~ 20000
//***********************************************************
for(i = 0; i<N; i++) scanf("%d",&ar[i]);
sort(ar.begin(),ar.end());
//calculate smallest difference
int small = ar[k-1] - ar[0];
for(i = k-1; i<N; i++){
int temp;
if( temp = ar[i] - ar[i-k+1] < small) small = temp;
}
cout<<small <<endl;//print smallest difference
}
return 0;
}
When I changed the type to array it ran perfectly fine. What is the problem with using vectors?
Your code has a lack of error checking:
Check that cin >> N >> k succeeded.
Check that each scanf succeeded.
Check k -1 is within range of the array bounds.
Any of those failures could cause your problem.
There is also a logic error on this line:
if( temp = ar[i] - ar[i-k+1] < small) small = temp;
The control expression is parsed as temp = (ar[i] - ar[i-k+1] < small), so this line will set small = 1 if ar[i] - ar[i-k+1] < small and do nothing otherwise. You probably meant (temp = ar[i] - ar[i-k+1]) < small).

Segmentation fault (core dumped) with sieve algorithm

I've been trying to implement the sieve algorithm using the following code:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector <int> primes; //all the primes found
int theLimit = 10E5;
void sieve (vector <int> &primes, int theLimit); //declaring the function
sieve (primes, theLimit);
return 0;
}
void sieve (vector <int> &primes, int theLimit) {
const int SIZE = theLimit + 1;
bool oddNonPrimes[SIZE]; //the array that tells you that tells you if the number that represents the current index is a non-prime or not
for (int i = 0; i < theLimit; ++i) //setting all the array indicies to false
oddNonPrimes[i] = false;
primes.push_back(2);
for (int i = 3; i < theLimit; i += 2){ //start searching for primes,we start with the number 3 and check all odd numbers only
if (!oddNonPrimes[i]){
int currNum = i;
primes.push_back(currNum);
for (int factor = 2; currNum <= theLimit; ++factor){
currNum *= factor;
oddNonPrimes[currNum] = true;
currNum = i;
}
}
}
}
I've tried lowering the size to make sure I'm not using too much memory but it still didn't work.I've also tried searching for an answer but I haven't found any.
What could be causing the Seg fault?and why?
First of all i would like to tell that the for loop which is been run for searching for all the primes should all the primes by seeing if(!oddNonPrimes[i]) is true or not should be done only for sqrt(theLimit) as it would lead to less complexity.
below is a sieve method that i would like you to refer to.
#include<bits/stdc++.h>
using namespace std;
bool *primality=new bool[10000010];
long long int *p = new long long int[1000001];
int main(){
long long count=0;
for(long long int i=0; i<10000010; i++)
primality[i]=true;
for(int i=2; i<10010; i++)
if(primality[i])
for(long long j=i*i; j<10000010; j+=i)
primality[j]=false;
for(int i=2; i<10000010; i++)
if(primality[i]){
p[count]=i;
count++;
}
}
This has been taken just from one of my codes . i think it would help you. :)
First,Sorry for wasting your time.
I should have used:
for (int factor = 2; (currNum * factor) <= theLimit; ++factor)
Instead of:
for (int factor = 2; currNum <= theLimit; ++factor)
Otherwise when the currNum is big and then multiplied by the factor,it might become larger than the limit and thus it tries to access an index beyond the array's size.

Sieve of Eratosthenes C++ Implementation: not exiting loop

I'm trying to implement the Sieve by myself and with no help other than the algorithm provided...
#include <iostream>
using namespace std;
void findPrimeNumbers(int number) {
int n=0;
bool* boolArray = new bool[number]();
for(int i=0; i<number; i++) {
boolArray[i] = true;
}
for(int i = 2; i<(int)sqrt(number); i++) {
cout << "calculating...\n";
if(boolArray[i]) {
for(int j=(i^2+(n*i)); j<number; n++)
boolArray[j] = false;
}
if(boolArray[i])
cout << i << "\n";
}
return;
}
int main()
{
findPrimeNumbers(55);
system("pause");
return 0;
}
Except the program is hanging on line 37; specifically, "boolArray[j] = false". It's never exiting that loop, and I don't know why.
Edited: Ok, this fixes the hang but still isn't right, but don't answer, I want to figure it out :)
#include <iostream>
#include <cmath>
using namespace std;
void findPrimeNumbers(int number) {
int n=0;
bool* boolArray = new bool[number]();
for(int i=0; i<number; i++) {
boolArray[i] = true;
}
for(int i = 2; i<sqrt(number); i++) {
if(boolArray[i]) {
for (int j = pow(i,2) + n*i; j <= number; j = pow(i, 2) + (++n*i))
boolArray[j] = false;
}
if(boolArray[i] && number % i == 0)
cout << i << "\n";
}
return;
}
int main()
{
findPrimeNumbers(13195);
system("pause");
return 0;
}
Beyond the error pointed out by #Rapptz (^ is bitwise xor), you are incrementing n instead of j, so the termination condition is never reached.
Two problems:
The ^ operator is not the exponent operator like it is in some other languages. Just multiply i by itself instead (i*i).
your for loop:
for(int j=(i^2+(n*i)); j<number; n++)
boolArray[j] = false;
does not reevaluate the initial condition each loop. You need to reevaluate the condition at the beginning of the for loop:
for(int n=0; j<number; n++)
{
j=(i*i+(n*i));
boolArray[j] = false;
}
Your issue is the line i^2+(n*i) like the comments point out, operator^ is the XOR operator, not exponentiation. In order to exponentiate something you have to include the <cmath> header and call std::pow(a,b) where it is equivalent to the mathematical expression a^b.
Although you didn't ask for code review, it should be noted that using dynamic allocation for a bool array is probably not a good idea. You should use std::vector<bool> and a proper reserve call. It should also be noted that the pow call would be completely unnecessary, as you are only multiplying it by itself (i.e. 2^2 is the same as 2*2).
A better naive prime sieve would be something similar to this:
#include <vector>
#include <iostream>
template<typename T>
std::vector<T> generatePrimes(unsigned int limit) {
std::vector<T> primes;
std::vector<bool> sieve((limit+1)/2);
if(limit > 1) {
primes.push_back(2);
for(unsigned int i = 1, prime = 3; i < sieve.size(); ++i, prime += 2) {
if(!sieve[i]) {
primes.push_back(prime);
for(unsigned int j = (prime*prime)/2; j < sieve.size(); j += prime)
sieve[j] = true;
}
}
}
return primes;
}
int main() {
std::vector<unsigned> primes = generatePrimes<unsigned>(1000000);
for(auto& i : primes)
std::cout << i << '\n';
}
You can see it here.
You have a number of problems:
int j=(i^2+(n*i))
^ is not power in C++, it's the bitwise XOR operator. To fix this, you'll need to #include <cmath> and utilize pow, or simply use i * i.
Secondly, as others have mentioned, you are incrementing n. The easiest fix for this is to use a while loop instead:
int j = std::pow(i, 2) + (n*i);
while(j < number) {
//Set bool at index to false
j += i;
}
Thirdly, you have a memory leak - you new without a delete. Further, there's no reason to use new here, instead you should have:
bool b[number];
This will deallocate b automatically when the function exits.
Finally, why return at the bottom of a void function? Technically you can do it, but there is no reason to.

vector subscript out of range error in c++

I am trying to write a program that takes an input of of n integers, and finds out the one that occurs the maximum number of times in the given input. I am trying to run the program for t cases.
For this, I have implemented a counting sort like algorithm (perhaps a bit naiive), that counts the number of occurrences of each number in the input. In case there are multiple numbers with the same maximum occurrence, I need to return the smaller among those. For this, I implemented sorting.
The issue I am facing is, that every time I run the program on Visual C++, I am getting an error that tells "vector subscript out of range". Under Netbeans, it is generating a return value of 1 and exiting. Please help me find the problem
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int findmax(vector<int> a, int n)
{
int i,ret;
ret = 0;
for ( i = 0; i <n; i++)
{
if (a[i] > ret) {
ret = a[i];
}
}
return ret;
}
int main() {
int i = 0, j = 0, k = 0, n,m,r1,r2;
vector<int> a;
int t;
vector<int> buff;
cin>>t;
while(t--) {
cin>>n;
a.clear();
buff.clear();
for ( i = 0; i < n; i++) {
cin>>a[i];
}
sort(a.begin(),a.end());
m = findmax(a,n);
for ( j = 0; j < m+1; j++) {
buff[a[j]] = buff[a[j]] + 1;
}
k = findmax(buff,m+1);
for ( i = 0; i < m+1; i++) {
if (buff[i] == k) {
r1 = i;
r2 = buff[i];
break;
}
}
cout<<r1<<" "<<r2<<endl;
}
return 0;
}
After a.clear() the vector doesn't have any members, and its size is 0.
Add a call to a.resize(n) to make it the proper size. You also need to resize buff to whatever size it needs to be.
this line it's the culprit:
cin>>a[i];
you must use push_back:
cin >> temp;
a.push_back(temp);
or resize(n) before:
cin>>n;
a.resize(n);
for ( i = 0; i < n; i++) {
cin>>a[i];
}
then you should pass you vector by reference to findmax
int findmax(vector<int> &a, int n)
...
This isn't how you populate an array.
cin>>a[i];
You need to use the push_back() method or pre-allocate the appropriate size.
The problem is that you're illegally using indexes of your vector that don't exist (you never add any items to the vector). Since you know the size, you can resize it after you clear it:
a.clear();
a.resize(n);
buff.clear();
buff.resize(n);
for ( i = 0; i < n; i++) {
cin>>a[i];
}
will be out of range. The vector, as you construct it, has zero size.