Sieve of Eratosthenes C++ Implementation: not exiting loop - c++

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.

Related

Function not printing any solutions

So, I need to make a function that is going to return the chromatic number of a graph. The graph is given through an adjecency matrix that the function finds using a file name. I have a function that should in theory work and which the compiler is throwing no issues for, yet when I run it, it simply prints out an empty line and ends the program.
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
int Find_Chromatic_Number (vector <vector <int>> matg, int matc[], int n) {
if (n == 0) {
return 0;
}
int result, i, j;
result = 0;
for (i = 0; i < n; i++) {
for (j = i; j < n; j++) {
if (matg[i][j] == 1) {
if (matc[i] == matc[j]) {
matc[j]++;
}
}
}
}
for (i = 0; i < n; i++) {
if (result < matc[i]) {
result = matc[i];
}
}
return result;
}
int main() {
string file;
int n, i, j, m;
cout << "unesite ime datoteke: " << endl;
cin >> file;
ifstream reader;
reader.open(file.c_str());
reader >> n;
vector<vector<int>> matg(n, vector<int>(0));
int matc[n];
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
reader >> matg[i][j];
}
matc[i] = 1;
}
int result = Find_Chromatic_Number(matg, matc, n);
cout << result << endl;
return 0;
}
The program is supposed to use an freader to convert the file into a 2D vector which represents the adjecency matrix (matg). I also made an array (matc) which represents the value of each vertice, with different numbers corresponding to different colors.
The function should go through the vector and every time there is an edge between two vertices it should check if their color value in matc is the same. If it is, it ups the second vale (j) by one. After the function has passed through the vector, the matc array should contain n different number with the highest number being the chromatic number I am looking for.
I hope I have explained enough of what I am trying to accomplish, if not just ask and I will add any further explanations.
Try to make it like that.
Don't choose a size for your vector
vector<vector<int> > matg;
And instead of using reader >> matg[i][j];
use:
int tmp;
reader >> tmp;
matg[i].push_back(tmp);

Why does the compiler skip the for-loop?

I have tried to do some practice with vector, and I made a simple for loop to calculate the sum of the elements within the vector. The program did not behave in the way I expect, so I try to run a debugger, and to my surprise, somehow, the compiler skips the for loop altogether, and I have not come up with a reasonable explanation.
//all code is written in cpp
#include <vector>
#include <iostream>
using namespace std;
int simplefunction(vector<int>vect)
{
int size = vect.size();
int sum = 0;
for (int count = 0; count == 4; count++) //<<--this for loop is being skipped when I count==4
{
sum = sum + vect[count];
}
return sum; //<<---the return sum is 0
}
int main()
{
vector<int>myvector(10);
for (int i = 0; i == 10; i++)
{
myvector.push_back(i);
}
int sum = simplefunction(myvector);
cout << "the result of the sum is " << sum;
return 0;
}
I have done some research, and usually the ill-defined for loop shows up when the final condition cannot be met (Ex: when setting count-- instead of count++)
Your loop's conditions are wrong, as they are always false!
Look at to the loops there
for (int i = 0; i == 10; i++)
// ^^^^^^^-----> condition : is it `true` when i is 0 (NO!!)
and
for (int count=0; count==4; count++)
// ^^^^^^^^^-----> condition : is it `true` when i is 0 (NO!!)
you are checking i is equal to 10 and 4 respectively, before incrementing it. That is always false. Hence it has not executed further. They should be
for (int i = 0; i < 10; i++) and for (int count=0; count<4; count++)
Secondly, vector<int> myvector(10); allocates a vector of integers and initialized with 0 s. Meaning, the loop afterwards this line (i.e. in the main())
for (int i = 0; i == 10; i++) {
myvector.push_back(i);
}
will insert 10 more elements (i.e. i s) to it, and you will end up with myvector with 20 elements. You probably meant to do
std::vector<int> myvector;
myvector.reserve(10) // reserve memory to avoid unwanted reallocations
for (int i = 0; i < 10; i++)
{
myvector.push_back(i);
}
or simpler using std::iota from <numeric> header.
#include <numeric> // std::iota
std::vector<int> myvector(10);
std::iota(myvector.begin(), myvector.end(), 0);
As a side note, avoid practising with using namespace std;

Function returning sum of even numbers in an array

So the prompt I was given was "Write a function that is given an array of ints and returns the sum of the even numbers in the array. The function is not given the length of array, but the last number in the array is -1. For example, if the array contains {2,3,5,4,-1} the function returns 6. Use the header int sumEven(int myArray[]). "
and the code I've written so far is
#include <iostream>
using namespace std;
int sumEven(int myArray[]){
int sum = 0;
for (int i=0; i++;){
if (myArray[i] >=0) {
sum+=myArray[i];
}
}
return sum;
}
But it keeps returning back zero's? I'm not seeing what I'm doing wrong here
The typical order of parameters to a for() loop are like so:
for(<initialize variable>; <end condition>; <increment variable>)
In your example, you have the i++ as your second parameter to the for loop, which is incorrect. It will return 0 (since i starts as 0, and i++ is post-increment, so it returns 0 and then increments to 1) and your for loop will exit immediately, since 0 evaluates to false.
Instead, replace the end condition with the end condition you've described: myArray[i] != -1. You should also include a check to see if the number is even before adding it to sum, which can be done by checking to see if the remainder when divided by 2 is 0.
#include <iostream>
using namespace std;
int sumEven(int myArray[]){
int sum = 0;
for (int i=0; myArray[i] != -1; i++){
if(myArray[i] % 2 == 0)
sum += myArray[i];
}
return sum;
}
The error is in the for loop. You should change the for loop to for (int i=0; ; i++) and you should also add a break statement to exit the for loop.
using namespace std;
int sumEven(int myArray[]){
int sum = 0;
for (int i=0; ; i++){
if (myArray[i] >=0) {
sum+=myArray[i];
}
else
{
break;
}
}
return sum;
}
int sumEven(int arr[]) {
int sum = 0;
// int len = (sizeof(arr)/sizeof(*arr)); // Since this will not work for all cases.
// auto len = end(arr) - begin(arr);
for (int i = 0; arr[i] >= 0; i++) {
if(arr[i]%2==0)
sum += arr[i];
}
return sum;
}
i guess the
for (int i=0; i++;){
make no iterations, cause condition to continue loop is "i++" - which is initialy zero.
Replace it with following for example
for (int i=0; i < array_length; i++;){

Splitting an array at a given value

Hello I am trying to split an array any time there is a negative value (excluding the negative value) and am a bit stuck at the moment. I tried an approach as seen in my code but I am not getting the desired output.
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
int main()
{
string line;
string filename;
int n,length;
std::vector<int>arr1;
fstream file("t1.txt");
if(file.is_open())
{
while(file >> n)
arr1.push_back(n);
for(int i =0; i < (int)arr1.size(); i++)
cout << arr1.at(i);
}
cout << endl;
int* arr2 = &arr1[0];
int arr3[arr1.size()/2];
int arr4[arr1.size()/2];
for(int i = 0; i < arr1.size(); i++)
{
cout << arr2[i];
}
for (int i =0; i < arr1.size(); i++)
{
if(i == -1)
break;
else
arr3[i] = arr2[i];
}
return 0;
}
The main problem is here:
int arr3[arr1.size()/2];
int arr4[arr1.size()/2];
This doesn't compile, and can be replaced with
std::vector<int> arr3; arr3.reserve(arr1.size() / 2);
std::vector<int> arr4; arr4.reserve(arr1.size() / 2);
I've added the "reserve" function so that the program doesn't have to allocate memory over and over in the loop.
Next, you are checking i in your loop, and your i loops from 0 to arr1.size() (which is unsigned so can't be negative) therefore i will never be negative.
What you really wanna check is what is in the arr1 vector at "i" position, and you can do so with the [] operator like
for (int i =0; i < arr1.size(); i++)
{
if (arr1[i] >= 0) //if the value is positive, we push it inside our arr3 vector
arr3.push_back(arr1[i]);
else
{
i++; //skip negative value
//
while (i < arr1.size())
{
if (arr1[i] > 0)
arr4.push_back(arr1[i]);
i++;
}
//
//or
//insert all the elemenents we haven't processed yet in the arr4 vector
//this code assumes those elements are positive values
//arr4.insert(arr4.begin(), arr1.begin() + i, arr1.end());
//break;
}
}
Of course this could be done in a different way, like instead of creating 2 vectors, you could just use the one you have generated already.
Hope this helps.
There are several problems in your code
you should not access the vector's data this way unless you really need to
you prepare arrays with predefined size without knowing where to expect the negative values
you do not assign anything to your array 4
you check the index for being negative, not the value
according to your text there could be several negative values leading to multiple result-arrays. You seem to be prepared for only two.
Here is some code that actually splits when encountering negative values:
std::vector<vector<int> > splitted;
for (int i = 0; i < arr1.size(); ++i)
{
if (i ==0 or arr1[i] < 0)
splitted.push_back(std::vector<int>());
if (arr1[i] >= 0)
splitted.back().push_back(arr1[i]);
}
Testing it:
for (int i = 0; i < splitted.size(); ++i)
{
for (int k = 0; k < splitted[i].size(); ++k)
{
std::cout << splitted[i][k];
}
if (splitted[i].empty())
std::cout << "(emtpy)";
std::cout << '\n';
}
Using the following test input
1 2 3 -1 1 -1 -1
You get the following output:
123
1
(emtpy)
(emtpy)

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.