Prime numbers program - c++

I'm currently trying out some questions just to practice my programming skills. ( Not taking it in school or anything yet, self taught ) I came across this problem which required me to read in a number from a given txt file. This number would be N. Now I'm suppose to find the Nth prime number for N <= 10 000. After I find it, I'm suppose to print it out to another txt file. Now for most parts of the question I'm able to understand and devise a method to get N. The problem is that I'm using an array to save previously found prime numbers so as to use them to check against future numbers. Even when my array was size 100, as long as the input integer was roughly < 15, the program crashes.
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <fstream>
using namespace std;
int main() {
ifstream trial;
trial.open("C:\\Users\\User\\Documents\\trial.txt");
int prime;
trial >> prime;
ofstream write;
write.open("C:\\Users\\User\\Documents\\answer.txt");
int num[100], b, c, e;
bool check;
b = 0;
switch (prime) {
case 1:
{
write << 2 << endl;
break;
}
case 2:
{
write << 3 << endl;
break;
}
case 3:
{
write << 5 << endl;
break;
}
case 4:
{
write << 7 << endl;
break;
}
default:
{
for (int a = 10; a <= 1000000; a++) {
check = false;
if (((a % 2) != 0) && ((a % 3) != 0) && ((a % 5) != 0) && ((a % 7) != 0)) // first filter
{
for (int d = 0; d <= b; d++) {
c = num[d];
if ((a % c) == 0) {
check = true; // second filter based on previous recorded primes in array
break;
}
}
if (!check) {
e = a;
if (b <= 100) {
num[b] = a;
}
b = b + 1;
}
}
if ((b) == (prime - 4)) {
write << e << endl;
break;
}
}
}
}
trial.close();
write.close();
return 0;
}
I did this entirely base on my dummies guide and myself so do forgive some code inefficiency and general newbie-ness of my algorithm.
Also for up to 15 it displays the prime numbers correctly.
Could anyone tell me how I should go about improving this current code? I'm thinking of using a txt file in place of the array. Is that possible? Any help is appreciated.

Since your question is about programming rather than math, I will try to keep my answer that way too.
The first glance of your code makes me wonder what on earth you are doing here... If you read the answers, you will realize that some of them didn't bother to understand your code, and some just dump your code to a debugger and see what's going on. Is it that we are that impatient? Or is it simply that your code is too difficult to understand for a relatively easy problem?
To improve your code, try ask yourself some questions:
What are a, b, c, etc? Wouldn't it better to give more meaningful names?
What exactly is your algorithm? Can you write down a clearly written paragraph in English about what you are doing (in an exact way)? Can you modify the paragraph into a series of steps that you can mentally carry out on any input and can be sure that it is correct?
Are all steps necessary? Can we combine or even eliminate some of them?
What are the steps that are easy to express in English but require, say, more than 10 lines in C/C++?
Does your list of steps have any structures? Loops? Big (probably repeated) chunks that can be put as a single step with sub-steps?
After you have going through the questions, you will probably have a clearly laid out pseudo-code that solves the problem, which is easy to explain and understand. After that you can implement your pseudo-code in C/C++, or, in fact, any general purpose language.

There are a two approaches to testing for primality you might want to consider:
The problem domain is small enough that just looping over the numbers until you find the Nth prime would probably be an acceptable solution and take less than a few milliseconds to complete. There are a number of simple optimizations you can make to this approach for example you only need to test to see if it's divisible by 2 once and then you only have to check against the odd numbers and you only have to check numbers less than or equal to the aquare root of the number being tested.
The Sieve of Eratosthenes is very effective and easy to implement and incredibly light on the math end of things.
As for why you code is crashing I suspect changing the line that reads
for( int d=0; d<=b; d++)
to
for( int d=0; d<b; d++)
will fix the problem because you are trying to read from a potentially uninitialized element of the array which probably contains garbage.

I haven't looked at your code, but your array must be large enough to contain all the values you will store in it. 100 certainly isn't going to be enough for most input for this problem.
E.g. this code..
int someArray[100];
someArray[150] = 10;
Writes to a location large than the array (150 > 100). This is known as a memory overwrite. Depending on what happened to be at that memory location your program may crash immediately, later, or never at all.
A good practice when using arrays is to assert in someway that the element you are writing to is within the bounds of the array. Or use an array-type class that performs this checking.
For your problem the easiest approach would be to use the STL vector class. While you must add elements (vector::push_back()) you can later access elements using the array operator []. Vector will also give you the best iterative performance.
Here's some sample code of adding the numbers 0-100 to a vector and then printing them. Note in the second loop we use the count of items stored in the vector.
#include <vector> // std::vector
...
const int MAX_ITEMS = 100;
std::vector<int> intVector;
intVector.reserve(MAX_ITEMS); // allocates all memory up-front
// add items
for (int i = 0; i < MAX_ITEMS; i++)
{
intVector.push_back(i); // this is how you add a value to a vector;
}
// print them
for (int i = 0; i < intVector.size(); i++)
{
int elem = intVector[i]; // this access the item at index 'i'
printf("element %d is %d\n", i, elem);
}

I'm trying to improve my functional programming at the moment so I just coded up the sieve quickly. I figure I'll post it here. If you're still learning, you might find it interesting, too.
#include <iostream>
#include <list>
#include <math.h>
#include <functional>
#include <algorithm>
using namespace std;
class is_multiple : public binary_function<int, int, bool>
{
public:
bool operator()(int value, int test) const
{
if(value == test) // do not remove the first value
return false;
else
return (value % test) == 0;
}
};
int main()
{
list<int> numbersToTest;
int input = 500;
// add all numbers to list
for(int x = 1; x < input; x++)
numbersToTest.push_back(x);
// starting at 2 go through the list and remove all multiples until you reach the squareroot
// of the last element in the list
for(list<int>::iterator itr = ++numbersToTest.begin(); *itr < sqrt((float) input); itr++)
{
int tmp = *itr;
numbersToTest.remove_if(bind2nd(is_multiple(), *itr));
itr = find(numbersToTest.begin(), numbersToTest.end(), tmp); //remove_if invalidates iterator
// so find it again. kind of ugly
}
// output primes
for(list<int>::iterator itr = numbersToTest.begin(); itr != --numbersToTest.end(); itr++)
cout << *itr << "\t";
system("PAUSE");
return 0;
}
Any advice on how to improve this would be welcome by the way.

Here is my code. When working on a big number, it's very slow!
It can calculate all prime numbers with in the number you input!
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;
int main()
{
int m;
int n=0;
char ch;
fstream fp;
cout<<"What prime numbers do you want get within? ";
if((cin>>m)==0)
{
cout<<"Bad input! Please try again!\n";
return 1;
}
if(m<2)
{
cout<<"There are no prime numbers within "<<m<<endl;
return 0;
}
else if(m==2)
{
fp.open("prime.txt",ios::in|ios::out|ios::trunc);//create a file can be writen and read. If the file exist, it will be overwriten.
fp<<"There are only 1 prime number within 2.\n";
fp<<"2\n";
fp.close();
cout<<"Congratulations! It has worked out!\n";
return 0;
}
else
{
int j;
int sq;
fp.open("prime.txt",ios::in|ios::out|ios::trunc);
fp<<"2\t\t";
n++;
for(int i=3;i<=m;i+=2)
{
sq=static_cast<int>(sqrt(i))+1;
fp.seekg(0,ios::beg);
fp>>j;
for(;j<sq;)
{
if(i%j==0)
{
break;
}
else
{
if((fp>>j)==NULL)
{
j=3;
}
}
}
if(j>=sq)
{
fp.seekg(0,ios::end);
fp<<i<<"\t\t";
n++;
if(n%4==0)
fp<<'\n';
}
}
fp.seekg(0,ios::end);
fp<<"\nThere are "<<n<<" prime number within "<<m<<".\n";
fp.close();
cout<<"Congratulations! It has worked out!\n";
return 0;
}
}

For one, you'd have less code (which is always a good thing!) if you didn't have special cases for 3, 5 and 7.
Also, you can avoid the special case for 2 if you just set num[b] = 2 and only test for divisibility by things in your array.

It looks like as you go around the main for() loop, the value of b increases.
Then, this results in a crash because you access memory off the end of your array:
for (int d = 0; d <= b; d++) {
c = num[d];
I think you need to get the algorithm clearer in your head and then approach the code again.

Running your code through a debugger, I've found that it crashes with a floating point exception at "if ((a % c) == 0)". The reason for this is that you haven't initialized anything in num, so you're doing "a % 0".

From what I know, in C/C++ int is a 16bit type so you cannot fit 1 million in it (limit is 2^16=32k). Try and declare "a" as long
I think the C standard says that int is at least as large as short and at most as large as long.
In practice int is 4 bytes, so it can hold numbers between -2^31 and 2^31-1.

Since this is for pedagogical purposes, I would suggest implementing the Sieve of Eratosthenes.

This should also be of interest to you: http://en.wikipedia.org/wiki/Primality_test

for(int currentInt=2; currentInt<=1000000; currentInt++)
{check = false; // Basically the idea for this for loop is to run checks against integers. This is the main for loop in this program. I re initialize check to false ( check is a bool declared above this. )
for( int arrayPrime=0; arrayPrime<currentPrime; arrayPrime++) // This for loop is used for checking the currentInt against previously found primes which are stored in the num array.
{ c=num[arrayPrime];
if ((currentInt%c)==0) { check = true;// second filter based on previous recorded primes in array
break;} // this is the check. I check the number against every stored value in the num array. If it's divisible by any of them, then bool check is set to true.
if ( currentInt == 2)
{ check = false; } // since i preset num[0] = 2 i make an exception for the number 2.
if (!check)
{
e=a;
if(currentPrime <= 100){
num[currentPrime]= currentInt;} // This if uses check to see if the currentInt is a prime.
currentPrime = currentPrime+1;} // increases the value of currentPrime ( previously b ) by one if !check.
if(currentPrime==prime)
{
write<<e<<endl;
break;} // if currentPrime == prime then write the currentInt into a txt file and break loop, ending the program.
Thanks for the advice polythinker =)

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <fstream>
using namespace std;
int main()
{
ifstream trial;
trial.open("C:\\Users\\User\\Documents\\trial.txt");
int prime, e;
trial>>prime;
ofstream write;
write.open("C:\\Users\\User\\Documents\\answer.txt");
int num[10000], currentPrime, c, primePrint;
bool check;
currentPrime=0;
num[currentPrime] = 2;
currentPrime=1;
for(int currentInt=2; currentInt<=1000000; currentInt++)
{check = false;
for( int arrayPrime=0; arrayPrime<currentPrime; arrayPrime++)
{ c=num[arrayPrime];
if ((currentInt%c)==0) { check = true;// second filter based on previous recorded primes in array
break;}
}
if (!check)
{ e=currentInt;
if( currentInt!= 2 ) {
num[currentPrime]= currentInt;}
currentPrime = currentPrime+1;}
if(currentPrime==prime)
{
write<<e<<endl;
break;}
}
trial.close();
write.close();
return 0;
}
This is the finalized version base on my original code. It works perfectly and if you want to increase the range of prime numbers simply increase the array number. Thanks for the help =)

Since you will need larger prime number values for later questions, I suggest you follow dreeves advice, and do a sieve. It is a very useful arrow to have in your quiver.

Related

1) Create dynamically filled array in a function. 2) Return the array content

I was doing a prime no# class (runs a function to check if inout is prime) and tried to take it a little further by printing what the prime numbers are for inputs that are prime. I managed to hack together an inelegant solution as you can see in the code, by wedging a for-loop in the middle of a cout.
I want to write a function that would create an array of all numbers that input num can be divided by, and then call the function in my main func.
int main() {
int num;
cout<<"Enter a number and we'll check if it's prime: ";
cin>>num;
isPrime(num);
if (isPrime(num) == true)
cout<<"Number is prime!";
else
{
cout<<"Not a prime number :( ";
cout<<"Infact, "<<num<<" can be divided by: ";
for(int i=2; i<num; i++) {
if(num % i == 0)
cout<<i<<", ";
}
//What I want:> cout<<"Infact, "<<num<<" can be divided by: "<<arrayOfDiiders;
}
return 0;
}
The below is quasi human language/c++ code, written to describe what I wanted to achieve.
int allDividers(int num) {
int arrayOfDiiders[]; //the array i wanted to make
for(int i=2; i<num; i++) {
if(num % i == 0)
// add i to the arrayOfDiiders[];
}
return arrayOfDiiders[];
}
Other func that assertions if user input is prime number. Included incase relevant.
bool isPrime(int num){
int countDivs = 0;
for(int i=1; i<=num; i++) {
if (num % i == 0)
countDivs++;
}
if (countDivs == 2)
return true;
else
return false;
}
Thanks in advance.
I managed to hack together an inelegant solution as you can see in the code, by wedging a for-loop in the middle of a cout.
Actually, this solution is much more elegant since it avoids the unnecessary cost of a dynamic array.
Create dynamically filled array in a function. 2) Return the array content
You can do it like this:
std::vector<int> v; // a dynamic array
// fill the vector here
return v;
You can use a std::vector:
#include <vector>
std::vector<int> factors;
for(int i=2; i<num; i++) {
if(num%i==0) {
factors.push_back(i);
}
}
for(int i:factors) cout<<i;
Actually you can combine both your requirements(checking if a num is prime ad getting all the dividors) into the same function.
I would do it this way
#include <iostream>
#include <set>
#include <cmath>
using namespace std;
static void getDividors(int num, set<int> &divs)
{
divs.insert(1);
divs.insert(num);
if (num == 2)
return;
// It is enough to check until the sqrt num..
int sqRootNum = floor(sqrt(num));
for (int i = 2; i <= sqRootNum; i++) {
if (num % i == 0) {
divs.insert(i);
divs.insert(num/i);
}
}
}
int main() {
int num;
cout<<"Enter a number and we'll check if it's prime: ";
cin>>num;
set<int> divs;
getDividors(num, divs);
bool isPrime = divs.size() > 2 ? false : true;
if (isPrime)
cout<<"Number is prime!";
else
{
cout<<"Not a prime number :( ";
cout<<"Infact, "<<num<<" can be divided by: ";
for (const auto &n : divs) {
cout<< n <<" ";
}
}
return 0;
}
Here is the sample output:
Enter a number and we'll check if it's prime: 16
Not a prime number :( Infact, 16 can be divided by: 1 2 4 8 16
The complexity of above code is O(sqrt(n)) which makes it very efficient too.
For insertion of elements, i am using set instead of vectors as it will simplify the logic as to not check for duplicates when adding into vector and also will be ordered(elements added to set will be in the ascending order) making it easy to nicely print them.
Since you wrote
The below is quasi human language/c++ code, written to describe what I wanted to achieve.
I'm adding this answer to show a solution that (maybe accepting to change our midset a bit) is truly like human language, because it tells a story, rather then using low lever for loops and if conditionals for which you have to pay attention on whether you've mistakely written <= instead of < and other stuff.
Here it is:
auto dividers = iota(2, num) | transform(both(id, mod(num)))
| filter(compose(equal_to(0), get_second))
| transform(get_first);
What does it do?
In short:
takes numbers from 2 to num-1,
std::pairs them up with the modulo of num by each of them,
retains only those with 0 modulo,
pulls the original number throwing away the modulo.
More in detail:
Iota is the ninth letter of the Greek alphabet, and ranges::views::iota (for which you can refer to std::ranges::views::iota) is such that iota(n) gives you back n, n+1, n+2, n+3, ..., whereas if you pass it a second argument, as in our usecase, it gives you back only numbers up to and not including that: iota(n, n+m) gives n, n+1, n+2, ..., n+m-1.
For ranges::views::transform you can refer to std::ranges::views::transfrom; we are passing to it both(id, mod(num)) as the transforming function, which, as the name should imply, applies both the identity funtion and mod(num) to its argument and gives you back a pair of those two results (it is not a standard function, I've written it at the bottom of this answer); mod(num), guess what, is such that nod(num)(n) == num % n (ditto, I've defined mod below, as a hana::curryed wrapper to %).
For ranges::views::filter you can refer to std::ranges::views::filter; we are passing to it the mathematical composition, via boost::hana::compose of two functions: get_second, which takes the second entry of the pair coming from the transform, i.e. the modulo, and equal_to(0) which is predicate testing if something is zero (equal_to is a curried std::equal_to<>{} function object).
Finally, we are pulling out only the first element of the pairs, via transform(get_first).
As an improvement to the code above, you could add | cache1 between the first of the two tranform and the filter after it. The reason why, is explained in this post here on Stack Overflow and in this post on FluentC++.
Below are the helper functions I've used with each header they need.
std::get is a template function, so it can't be passed around as an object could. BOOST_HOF_LIFT can make an object out of it:
#include <boost/hof/lift.hpp>
#include <utility>
template<int N>
auto constexpr get = BOOST_HOF_LIFT(std::get<N>);
so we can write more verbose getters for our usecase of working on pairs:
auto constexpr get_first = get<0>;
auto constexpr get_second = get<1>;
std::equal_to is already a function object, but we want to be able to pass its two arguments one by one, so we curry it:
#include <boost/hana/functional/curry.hpp>
#include <functional>
auto constexpr equal_to = curry<2>(std::equal_to<>{});
We want to do the same for %, but that's on operator, so we'd have to manually wrap it; luckily the STL offers an object already, namely std::modulus<>{}:
// same two headers as previous one
auto constexpr mod = curry<2>(std::modulus<>{});
Finally, here's my hand-made both (which could be greately improved, generalized):
#include <utility>
auto constexpr both = [](auto const& f1, auto const& f2){
return [&f1, &f2](auto const& x){
return std::make_pair(f1(x), f2(x));
};
};
Here's a working demo on Compiler Explorer.

Why is my randomly generated array outputting only zeroes?

I am writing a code that is supposed to act as a lottery. The lottery numbers available are 1-50, and there are 10 of them. The user is supposed to input one number and the program returns if the user's number matches one of the 10 random lottery numbers. I have gotten all of these parts down, but there is one problem; all 10 of the lottery numbers must be unique. I have gotten 10 unique numbers 1-50, but they weren't very random. The code I have written up to this point seems correct to me, except I know there is something missing (along with the fact that I can clean my code up a lot, but I'm focusing on the objective right now). Right now if I run the program it will return ten zeroes. I need each element in the lottery array to be a unique number from 1-50, and produce different sets of numbers each time i run the program. Any help would be appreciated.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using std::cout; using std::cin; using std::endl;
void printOut(int[]);
void draw(int[]);
bool check();
int fillFunc[10];
int main()
{
const int arraySize = 10;
int win[arraySize] = {};
srand((unsigned)time(NULL));
draw(win);
cout << "Your lottery numbers are: ";
printOut(win);
}
void draw(int fillFunc[])
{
int i;
for (i = 0; i < 10; i++)
{
if (check() == true)
continue;
fillFunc[i] = 1 + rand() % 50;
}
}
void printOut(int fillFunc[])
{
for (int i = 0; i < 10; i++)
{
cout << " " << fillFunc[i];
}
cout << "\n";
}
bool check()
{
for (int i = 0; i < 10; ++i)
{
if (fillFunc[i] == i)
return true;
}
return false;
}
(also don't ask me why the array has the name "win", this is what my prof wants me to call it)
Because check() always return true. At the start, the array is filled with zeroes so check returns true as win[0]==0 and that remains true forever as nothing changes that value. So in draw you always branch to continue and never modify anything.
To solve the problem one way could be to shuffle the sequence of 1-50 and extract the first 10 values of the shuffled array. You can use the very simple Fisher-Yates algorithm.
To answer your question that you updated in the comments you need to consider a shuffling algorithm.
I will give you an idea of how to do this that is O(n) so you don't have to "loop" thru your current list of numbers and keep checking to see if the new number was already picked...
your lottery max number is 50 so make an array of size 50 that is as follows:
lotteryNumber[0]=1
lotteryNumber[1]=2
...
lotteryNumber[49]=50
to pick a number to put into your "selected" numbers array...
indexToLotteryNumbers = rand() % 50 - numbersPickedSoFar;
randomLotteryNumber[i++] = lotteryNumber[ indexToLotteryNumbers ];
// this is the key "trick"
swap(&lotteryNumber[ indexToLotteryNumbers ], &lotteryNumber[49-numbersPickedSoFar]);
numbersPickedSoFar++;
Theory
The random numbers are the indexes and not the actual values
By swapping the number you picked with the outer element you don't care if your random number generator picks the same index because it will be different the next time.
look at a small example...say you have 1 2 3 4
rand() generates "2"
so your first # is 2 (assume 1-based indexing here) now you swap the (4th) element for the (2nd) element now you have 1 4 3 |2
(here |2 means you can't pick that number again because it's outside the
random # generator range) but you reduce the random # generation from
1-4 to 1 thru 3
rand() generates "1" so your number is "1" and you swap that with the "outer" unpicked number 3 4 |1 2
rand() generates
"2" again! your lottery number is 4 this time... and so on.
I hope this makes sense.
This is what I would do, given your constraints. Rather than check if a number is unique while you are filling the array, just pass the array into the function that chooses the number so it can return a unique value.
I also removed the redundant global array. It could be a source of bugs if you forgot to pass the local array you were working with to any of the functions.
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int getUniqueNumber(int fillFunc[])
{
while(true)
{
//pick number
int val = 1 + rand() % 50;
//assume it's unique
bool unique = true;
for (int i = 0; i < 10; ++i)
{
//if another number matches, it isn't unique, choose again
if (fillFunc[i] == val)
{
unique = false;
break;
}
}
//if it is unique, return it.
if (unique)
{
return val;
}
}
//never reached, but avoids an all control paths must return a value warning.
return -1;
}
void draw(int fillFunc[])
{
for (int i = 0; i < 10; i++)
{
fillFunc[i] = getUniqueNumber(fillFunc);
}
}
void printOut(int fillFunc[])
{
for (int i = 0; i < 10; i++)
{
cout << " " << fillFunc[i];
}
cout << "\n";
}
int main()
{
srand((unsigned)time(NULL));
const int arraySize = 10;
int win[arraySize] = {};
draw(win);
cout << "Your lottery numbers are: ";
printOut(win);
return 0;
}
There are other, perhaps better, ways to select unique numbers in a range, but I went for simple to implement and explain. You can read about some other methods in these questions:
Unique random numbers in an integer array in the C programming language
Unique (non-repeating) random numbers in O(1)?
You only assign a value to fillFunc[i] when i is 10, which is an out of bounds access. Move the assignment to inside the loop.
You have other problems too. If you do continue, you just leave an entry in the array unset.
You should try adding a lot of output statements to your program so you can more easily understand what it's doing. If you prefer, use a debugger to step through it.

Trouble sieving primes from a large range

#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int main() {
int t,m,n;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&m,&n);
int rootn=sqrt(double(n));
bool p[10000]; //finding prime numbers from 1 to square_root(n)
for(int j=0;j<=rootn;j++)
p[j]=true;
p[0]=false;
p[1]=false;
int i=rootn;
while(i--)
{
if(p[i]==true)
{
int c=i;
do
{
c=c+i;
p[c]=false;
}while(c+p[i]<=rootn);
}
};
i=0;
bool rangep[10000]; //used for finding prime numbers between m and n by eliminating multiple of primes in between 1 and squareroot(n)
for(int j=0;j<=n-m+1;j++)
rangep[j]=true;
i=rootn;
do
{
if(p[i]==true)
{
for(int j=m;j<=n;j++)
{
if(j%i==0&&j!=i)
rangep[j-m]=false;
}
}
}while(i--);
i=n-m;
do
{
if(rangep[i]==true)
printf("%d\n",i+m);
}while(i--);
printf("\n");
}
return 0;
system("PAUSE");
}
Hello I'm trying to use the sieve of Eratosthenes to find prime numbers in a range between m to n where m>=1 and n<=100000000. When I give input of 1 to 10000, the result is correct. But for a wider range, the stack is overflowed even if I increase the array sizes.
               
A simple and more readable implementation
void Sieve(int n) {
int sqrtn = (int)sqrt((double)n);
std::vector<bool> sieve(n + 1, false);
for (int m = 2; m <= sqrtn; ++m) {
if (!sieve[m]) {
cout << m << " ";
for (int k = m * m; k <= n; k += m)
sieve[k] = true;
}
}
for (int m = sqrtn; m <= n; ++m)
if (!sieve[m])
cout << m << " ";
}
Reason of getting error
You are declaring an enormous array as a local variable. That's why when the stack frame of main is pushed it needs so much memory that stack overflow exception is generated. Visual studio is tricky enough to analyze the code for projected run-time stack usage and generate exception when needed.
Use this compact implementation. Moreover you can have bs declared in the function if you want. Don't make implementations complex.
Implementation
typedef long long ll;
typedef vector<int> vi;
vi primes;
bitset<100000000> bs;
void sieve(ll upperbound) {
_sieve_size = upperbound + 1;
bs.set();
bs[0] = bs[1] = 0;
for (ll i = 2; i <= _sieve_size; i++)
if (bs[i]) { //if not marked
for (ll j = i * i; j <= _sieve_size; j += i) //check all the multiples
bs[j] = 0; // they are surely not prime :-)
primes.push_back((int)i); // this is prime
} }
call from main() sieve(10000);. You have primes list in vector primes.
Note: As mentioned in comment--stackoverflow is quite unexpected error here. You are implementing sieve but it will be more efficient if you use bistet instead of bool.
Few things like if n=10^8 then sqrt(n)=10^4. And your bool array is p[10000]. So there is a chance of accessing array out of bound.
I agree with the other answers,
saying that you should basically just start over. 
Do you even care why your code doesn’t work?  (You didn’t actually ask.)
I’m not sure that the problem in your code
has been identified accurately yet. 
First of all, I’ll add this comment to help set the context:
// For any int aardvark;
// p[aardvark] = false means that aardvark is composite (i.e., not prime).
// p[aardvark] = true means that aardvark might be prime, or maybe we just don’t know yet.
Now let me draw your attention to this code:
int i=rootn;
while(i--)
{
if(p[i]==true)
{
int c=i;
do
{
c=c+i;
p[c]=false;
}while(c+p[i]<=rootn);
}
};
You say that n≤100000000 (although your code doesn’t check that), so,
presumably, rootn≤10000, which is the dimensionality (size) of p[]. 
The above code is saying that, for every integer i
(no matter whether it’s prime or composite),
2×i, 3×i, 4×i, etc., are, by definition, composite. 
So, for c equal to 2×i, 3×i, 4×i, …,
we set p[c]=false because we know that c is composite.
But look closely at the code. 
It sets c=c+i and says p[c]=false
before checking whether c is still in range
to be a valid index into p[]. 
Now, if n≤25000000, then rootn≤5000. 
If i≤ rootn, then i≤5000, and, as long as c≤5000, then c+i≤10000. 
But, if n>25000000, then rootn>5000,†
and the sequence i=rootn;, c=i;, c=c+i;
can set c to a value greater than 10000. 
And then you use that value to index into p[]. 
That’s probably where the stack overflow occurs.
Oh, BTW; you don’t need to say if(p[i]==true); if(p[i]) is good enough.
To add insult to injury, there’s a second error in the same block:
while(c+p[i]<=rootn). 
c and i are ints,
and p is an array of bools, so p[i] is a bool —
and yet you are adding c + p[i]. 
We know from the if that p[i] is true,
which is numerically equal to 1 —
so your loop termination condition is while (c+1<=rootn);
i.e., while c≤rootn-1. 
I think you meant to say while(c+i<=rootn).
Oh, also, why do you have executable code
immediately after an unconditional return statement? 
The system("PAUSE"); statement cannot possibly be reached.
(I’m not saying that those are the only errors;
they are just what jumped out at me.)
______________
† OK, splitting hairs, n has to be ≥ 25010001
(i.e., 50012) before rootn>5000.

Need advice on improving my code: Search Algorithm

I'm pretty new at C++ and would need some advice on this.
Here I have a code that I wrote to measure the number of times an arbitrary integer x occurs in an array and to output the comparisons made.
However I've read that by using multi-way branching("Divide and conqurer!") techniques, I could make the algorithm run faster.
Could anyone point me in the right direction how should I go about doing it?
Here is my working code for the other method I did:
#include <iostream>
#include <cstdlib>
#include <vector>
using namespace std;
vector <int> integers;
int function(int vectorsize, int count);
int x;
double input;
int main()
{
cout<<"Enter 20 integers"<<endl;
cout<<"Type 0.5 to end"<<endl;
while(true)
{
cin>>input;
if (input == 0.5)
break;
integers.push_back(input);
}
cout<<"Enter the integer x"<<endl;
cin>>x;
function((integers.size()-1),0);
system("pause");
}
int function(int vectorsize, int count)
{
if(vectorsize<0) //termination condition
{
cout<<"The number of times"<< x <<"appears is "<<count<<endl;
return 0;
}
if (integers[vectorsize] > x)
{
cout<< integers[vectorsize] << " > " << x <<endl;
}
if (integers[vectorsize] < x)
{
cout<< integers[vectorsize] << " < " << x <<endl;
}
if (integers[vectorsize] == x)
{
cout<< integers[vectorsize] << " = " << x <<endl;
count = count+1;
}
return (function(vectorsize-1,count));
}
Thanks!
If the array is unsorted, just use a single loop to compare each element to x. Unless there's something you're forgetting to tell us, I don't see any need for anything more complicated.
If the array is sorted, there are algorithms (e.g. binary search) that would have better asymptotic complexity. However, for a 20-element array a simple linear search should still be the preferred strategy.
If your array is a sorted one you can use a divide to conquer strategy:
Efficient way to count occurrences of a key in a sorted array
A divide and conquer algorithm is only beneficial if you can either eliminate some work with it, or if you can parallelize the divided work parts accross several computation units. In your case, the first option is possible with an already sorted dataset, other answers may have addressed the problem.
For the second solution, the algorithm name is map reduce, which split the dataset in several subsets, distribute the subsets to as many threads or processes, and gather the results to "compile" them (the term is actually "reduce") in a meaningful result. In your setting, it means that each thread will scan its own slice of the array to count the items, and return its result to the "reduce" thread, which will add them up to return the final result. This solution is only interesting for large datasets though.
There are questions dealing with mapreduce and c++ on SO, but I'll try to give you a sample implementation here:
#include <utility>
#include <thread>
#include <boost/barrier>
constexpr int MAP_COUNT = 4;
int mresults[MAP_COUNT];
boost::barrier endmap(MAP_COUNT + 1);
void mfunction(int start, int end, int rank ){
int count = 0;
for (int i= start; i < end; i++)
if ( integers[i] == x) count++;
mresult[rank] = count;
endmap.wait();
}
int rfunction(){
int count = 0;
for (int i : mresults) {
count += i;
}
return count;
}
int mapreduce(){
vector<thread &> mthreads;
int range = integers.size() / MAP_COUNT;
for (int i = 0; i < MAP_COUNT; i++ )
mthreads.push_back(thread(bind(mfunction, i * range, (i+1) * range, i)));
endmap.wait();
return rfunction();
}
Once the integers vector has been populated, you call the mapreduce function defined above, which should return the expected result. As you can see, the implementation is very specialized:
the map and reduce functions are specific to your problem,
the number of threads used for map is static,
I followed your style and used global variables,
for convenience, I used a boost::barrier for synchronization
However this should give you an idea of the algorithm, and how you could apply it to similar problems.
caveat: code untested.

Finding Palindromes from the product of two numbers with N digits

My code compiles but seems as if it may never find the answer. This is odd since I have looked at code that is almost identical that finishes in seconds.
Here is my code:
#include <iostream>
#include <sstream>
int main()
{
for(int i = 999; i >=100; i--)
{
for(int j=999; j>=100;j--)
{
int num = (i*j);
std::string number;
std::string temp;
std::string reversed;
std::stringstream out;
out << num;
number = out.str();
temp = number;
std::reverse(temp.begin(),temp.end());
if( temp == number)
{
std::cout << number << std::endl;
}
}
}
std::cin.get();
return 0;
}
Now here is code that I know works and works incredibly fast. I don't see what we are doing differently.
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
// Count down from largest to smallest, so first palindrome found is the largest
unsigned biggestProduct = 0;
for(unsigned n1=999; n1>=100; --n1) {
for(unsigned n2=999; n2>=100; --n2) {
unsigned thisProduct = n1 * n2;
if(thisProduct > biggestProduct) {
stringstream strmProduct;
string strProductReverse;
strmProduct << n1 * n2;
strProductReverse = strmProduct.str();
reverse(strProductReverse.begin(), strProductReverse.end());
if(strmProduct.str() == strProductReverse)
biggestProduct = thisProduct;
}
}
}
cout << biggestProduct << endl;
cin.get();
return 0;
}
for(int i = 999; i <=100; i--)
Will this ever run (same for j)? :)
for(int i = 999; i >=100; i--)
The biggest difference is this line if(thisProduct > biggestProduct). If the product is smaller than the current biggest you don't have to check whether is palindrome.
OK, assuming a correction to the for loops, there's an important difference in the two pieces of code. The second faster piece of code only attempts to find the largest palindrome, so it avoids a lot of work. Your code attempts to find all palindromes which is obviously a harder problem and is going to take more time.
The difference between the two is that the first tests for palindromeness for every i*j, while the other only tests i*j greater than the biggest palindrome its already found.
It can be made slightly faster by going from j= i to j>=100 and earlying out when i*j<= biggestProduct or when i*i<= biggestProduct.
Here are couple issues I can point to:
This line of code: for(int j=999; j>=100;j--) can be reduced to for(int j=999; j>=i-1;j--).This is to avoid running through number twice.
example: for i=999 you will go through j counter, starting with 999, followed by 998, 997, etc. It would save time if you skip everything lower or equal to 998 since i=<998 and j=999 would make those combinations
The second hint is in the question: you are looking for the largest, meaning that the first palindrome is the largest. So you need to filter whatever combination you have beyond that. You have it in the second code by adding if(thisProduct > biggestProduct).
Also steps for the counter can be crucial. From this discussion I found that changing the step size to 2 could be useful.
Last but not least is strings. I learnt here also that making strings could be computationally expensive. Editing the block with std::string could be another option.