Segmentation fault (core dumped) with sieve algorithm - c++

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.

Related

Memoizing Vector not taking values in a recursive function's return statement

With this code I was trying to calculate unique ways to reach a certain sum by adding array elements with a dynamic programming approach, the program works correctly but takes more time than expected so I checked if it is storing calculated values in the my vector, but it not storing any values at all.
#include <iostream>
#include <vector>
using namespace std;
// recursive function to include/excluded every element in the sum.
long long solve(int N,int sum, int* coins, long long mysum, vector<vector<long long >> &my, long long j){
if (mysum == sum){
return 1;
}if (mysum>sum){
return 0;
}
if (my[mysum][j]!=-1){
return my[mysum][j];
}
long long ways = 0;
while (j<N){
ways+= solve (N,sum,coins,mysum+coins[j],my, j);
j++;
}
//Line in question
return my[mysum][j] = ways;
}
int main() {
// code here.
int N=3;
int coins[] = {1,2,3};
int sum =4;
int check = INT_MIN;
vector<vector<long long int>> my(sum+1,vector<long long int>(N+1,-1));
cout<< solve (N,sum,coins,0,my,0)<< " ";
// traversing to check if the memoizing vector stored the return values
for (int x=0; x<sum+1; x++){
for (int y=0; y<N; y++){
if (my[x][y]!=-1){
check = 0;
}
}
}
cout<< check;
return 0;
}
output: 4 -2147483648
It does store the values, your checking code is not correct.
Try this version in your check
for (int y=0; y<N+1; y++){ // N+1 not N
So, the problem is that j is incrementing because of the for loop. The function fills my[newsum][j] only after the for loop's scope is over. By that time j==N and only my[newsum][N] is filled, the preceding values of j are left empty. This can be solved by make another variable equal to j that isn't incremented.

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

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.

Find the first and last indices of an array for which the sequential sum of elements from and to will be the largest

I have an array of integers A [N]. I want to find indices n and m such that the sequential sum from the nth element to the mth is maximum. Search time is limited by the value of N.
It's my code:
#include <iostream>
#include <vector>
using namespace std;
int MaxSum(vector<int> &A){
int N=A.size();
int n=0;
int m=0;
int prev_max=A[0];
int sol_max=A[0];
for (int i=1; i<N; i++){
prev_max=max(A[i], A[i]+prev_max);
if (prev_max>=sol_max){
sol_max=prev_max;
}
}
cout<<"m="<<m<<endl;
cout<<"n="<<n<<endl;
// cout<<sol_max<<endl;
}
int main()
{
vector<int> a={{-2},{1},{-3},{4},{-1},{2},{1},{-5},{4}};//for example: n=3; m=6
MaxSum(a);
}
I tried to insert these counters and each time the program didn't work correctly, and it is clear why. But, unfortunately, I don't know how to put them correctly (I hope you can fix it
This type of problem can be solved using Kadane's Algorithm and the complexity is linear.
The primary idea of this problem is to look for positive contiguous segments of the array. And finding the maximum sum among all positive contiguous segment. And also ignore segment that has negative sum (as we are intended to find the maximum sum).
Note: This idea will fail if all the values are negative. To fix this issues you can check if all the elements are negative or not and find the maximum value.
int MaxSum(vector<int>&A) {
int n=0,m=0;
int max_so_far=0,max_ending_here=0;
int prevIndex = 0;
for(int i=0;i<A.size();i++) {
max_ending_here += A[i];
if(max_ending_here > max_so_far) {
max_so_far = max_ending_here;
n = prevIndex;
m = i;
}
if(max_ending_here < 0) {
max_ending_here = 0;
prevIndex=i+1;
prevIndex=i+1;
}
}
cout<<"n: "<<n<<endl;
cout<<"m: "<<m<<endl;
}

The Sieve of Eratosthenes and Goldbach's Conjecture

The Sieve of Eratosthenes and Goldbach's Conjecture
Implement the Sieve of Eratosthenes and use it to find all prime
numbers less than or equal to one million. Use the result to
prove Goldbach's Conjecture for all even integers between four and
one million, inclusive.
Implement a function with the following declaration:
void sieve(int array[], int num);
This function takes an integer array as its argument. The array
should be initialized to the values 1 through 1000000. The
function modifies the array so that only the prime numbers remain;
all other values are zeroed out.
This function must be written to accept an integer array of any
size. You must should output for all primes numbers between 1 and
1000000, but when I test your function it may be on an array of a
different size.
Implement a function with the following declaration:
void goldbach(int array[], int num);
This function takes the same argument as the previous function
and displays each even integer between 4 and 1000000 with two
prime numbers that add to it.
The goal here is to provide an efficient implementation. This
means no multiplication, division, or modulus when determining if
a number is prime. It also means that the second function must find
two primes efficiently.
Output for your program: All prime numbers between 1 and 1000000
and all even numbers between 4 and 1000000 and the two prime
numbers that sum up to it.
DO NOT provide output or a session record for this project!
This is the code that I have so far, my problem is that it displays numbers higher than 1,000 as 1s, how can I go about this, thank you!
#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
void sieve(int array[], int num);
void goldbach(int array[], int num);
const int arraySize = 1000000;
int nums[arraySize];
int main(){
for (int i = 0; i <= arraySize; ++i)
nums[i] = 1;
nums[0] = nums[1] = 0;
sieve(nums, arraySize);
for(int i = 0; i < 10000; ++i){
if (nums[i] > 0){
cout << nums[i] << " ";
}
}
goldbach(nums, arraySize);
return 0;
}
void sieve(int array[], int num) {
int squareR = (int)sqrt(num);
for(int i = 2; i <= squareR; ++i){
int k;
if(array[i]){
for(k = i*i; k <= num; k += i)
array[k] = 0;
}
if (array[i] == 1){
array[i] = i;
}
}
}
void goldbach(int array[], int num){
int i, r = 0;
for (i = 4; i <= num; i += 2){
for (int j = 2; j <= i/2; j++)
if (array[j] && array[i-j]) r ++;
}
}
my problem is that it displays numbers higher than 1,000 as 1s, how can I go about this
That's because you're not updating the values in the array above 1000, here:
for(int i = 2; i <= squareR; ++i){
...
if (array[i] == 1){
array[i] = i;
clearly the array's entries above squareR are not updated and remain at the value you initialized them, which is 1.
However I you don't need this update at all. You can drop it and simplify your code, keeping the array's entries as either 1 (for primes) or 0 (for non-primes). with this, and display your result like this (in main):
for(int i = 0; i < arraySize; ++i){
if (nums[i] != 0){
// cout << nums[i] << " "; // <-- drop this
cout << i << " "; // <-- use this
}
}

Using vector to solve Sieve of Eratosthenes with C++ and recieving unusual error message

Previously today, I asked a question about implementing a Sieve of Eratosthenes with 2D arrays and was told by a few people to use vectors instead. The only problem is I had no idea how to use Vectors in C++.
I have rewritten my program today using a vector instead of a 2D array and it was going quite well until near the end of the program, where I receive the following error:
sieve.h: In function ‘void printPrimes(std::vector*, int)’:
sieve.h:42:20: error: no match for ‘operator<<’ in ‘std::cout << *(primes + ((unsigned int)(((unsigned int)i) * 12u)))’
I have never received this kind of error message before so I am unsure of how to fix this.
Here is my revised code:
sieve.h
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <vector>
using namespace std;
vector<int> calc_primes(int);
void printPrimes(int[]);
vector<int> calc_primes(int max)
{
vector<int> primes;
for(int i = 2; i < max; i++)
{
primes.push_back(i);
}
// for each value in the vector
for(int i = 0; i < primes.size(); i++)
{
//get the value
int v = primes[i];
if (v!=0) {
//remove all multiples of the value
int x = i+v;
while(x < primes.size()) {
primes[x]=0;
x = x+v;
}
}
}
return primes;
}
void printPrimes(vector<int>* primes, int size)
{
int primearray[size];
for(int i = 0; i < size; i++)
{
cout<<primes[i]<<endl;
}
}
sieve.cpp
#include "sieve.h"
using namespace std;
int main()
{
int max;
cout<<"Please enter the max amount of prime numbers:"<<endl;
cin>>max;
vector<int> primes = calc_primes(max);
printPrimes(primes, max);
return 0;
}
Your loop looks like this:
for(int i = 0; i < size; i++)
{
cout<<primes[i]<<endl;
}
but since primes is a pointer to a vector, this is treating primes as if it was an array of vectors, and by using primes[i] you are accessing the ith vector in the array of vectors, whereas you meant to access the ith element of the single vector that is passed to the function.
To fix it, just change this:
void printPrimes(vector<int>* primes, int size)
to this
void printPrimes(const vector<int> & primes, int size)
Now you are saying that primes is a reference to a vector, and primes[i] is then the ith element of that vector.
void printPrimes(vector<int>* primes, int size)
{
int primearray[size];
for(int i = 0; i < size; i++)
{
cout<<(*primes)[i]<<endl;
}
}
primes is a pointer, however, you want to print the value in a vector. *primes is the vector primes point to, so the solution is *(primes)[i]