Is there a better algorithm to find connected clusters? - c++

I'd like to find a better algorithm to find connected clusters.
For example, if I input:
(8, 6),
(1, 8),
(3, 5)
, then there are two connected clusters: <1,6,8> and <3,5>.
I tried to do that using Depth First Search, but it spent too much time (several days) when the inputs are very very substantial.
By the way, I tried to use igraph library; it was faster, but memory leak happened, my computer got breakdown.
My code (DFS) is below.
#ifndef GRAPH_I_H
#define GRAPH_I_H
#include <iostream>
#include <ctime>
#include <cmath>
#include <queue>
#include <mechsys/linalg/matvec.h>
using namespace std;
class Graph_i
{
public:
int NumOfFractures;
Array<Array<int>> G;
Array<int> Visited;
public:
Graph_i(const int NumOfFractures_1, const Array<int> Connections);
void DFS(int V, Array<int> &B);
void CreateGraph_i(Array<Array<int>> &S);
};
inline Graph_i::Graph_i(const int NumOfFractures_1, const Array<int> Connections)
{
NumOfFractures = NumOfFractures_1;
G.resize(NumOfFractures);
for (int i = 0; i < NumOfFractures; ++i)
G[i].resize(NumOfFractures);
for (int i = 0; i < NumOfFractures; ++i)
{
for (int j = 0; j < NumOfFractures; ++j)
G[i][j] = 0;
}
for (int i = 0; i < Connections.Size() / 2; ++i)
{
G[Connections[2 * i]][Connections[2 * i + 1]] = 1;
G[Connections[2 * i + 1]][Connections[2 * i]] = 1;
}
Visited.resize(NumOfFractures);
for (int i = 0; i < NumOfFractures; ++i)
{
Visited[i] = 0;
}
}
inline void Graph_i::DFS(int V, Array<int> &B)
{
Visited[V] = 1;
B.Push(V);
for (int i = 0; i < NumOfFractures; ++i)
{
if (Visited[i] == 0 && G[V][i] == 1)
DFS(i, B);
}
}
inline void Graph_i::CreateGraph_i(Array<Array<int>> &S)
{
if (S.Size() != 0)
{
std::cout << "Error! ListOfClusters should be empty array!\n";
exit(0);
}
for (int i = 0; i < NumOfFractures; ++i)
{
if (Visited[i] == 0)
{
Array<int> A;
DFS(i, A);
S.Push(A);
}
}
}
#endif
Main function (this is just one time loop; actually, in my code, there are many loops; and I have used OpenMP):
#include <Graph_i.h>
int main()
{
Array<int> Connections; //this is the input, containing pairs, e.g., 1,2,1,3,5,6; so, <1,2,3> is a connected cluster, <5,6> is also a cluster; so, I need algorithm to identify them
//size of this array can be very very large
Array< Array<int> > Listofclusters;// this two order array is used to recode connected clusters
Graph_i G(Connections.Size(), Connections);
G.CreateGraph_i(Listofclusters);
return 0;
}

Related

Subgraph with max nodes

I have the graph with N nodes. I have to create the longest subgraph (with max nodes). One node can be connected with only 2 nodes. So which nodes should I take to create this (max) subgraph?
What I'm doing is:
1: From initial node. I start 2 DFS functions. (from anothers nodes only 1).
2: For some node in DFS I use F() function to check all neighbours and find maximum way that I have to go. Then I'm saving the index of the node in which I have to go in index variable and starting DFS from index.
The problem is that this algorithm is too slow. How can I optimize it? Maybe there is special algorithm to find maximum subgraph?
Here is my code:
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
int used[20];
int m[20][20];
int c;
int F(int v) {
used[v] = 1;
int maxn = 0, index = -1, t;
for(int i = 0; i < c; ++i) {
if(!used[i] && m[v][i] == 1) {
t = F(i);
if(t > maxn) {
maxn = t;
index = i;
}
}
}
if(index != -1) {
used[v] = 0;
return maxn + 1;
}
else {
used[v] = 0;
return 1;
}
}
int DFS(int v) {
used[v] = 1;
int maxn = 0, index = -1, t;
for(int i = 0; i < c; ++i) {
if(!used[i] && m[v][i] == 1) {
t = F(i);
if(t > maxn) {
maxn = t;
index = i;
}
}
}
if(index != -1) {
return DFS(index) + 1;
}
else {
return 0;
}
}
int main() {
cin >> c;
for(int i = 0; i < c; ++i) {
for(int j = 0; j < c; ++ j)
cin >> m[i][j];
}
int maxn = DFS(0) + DFS(0) + 1;
cout << maxn << endl;
}

Is there any input for which selection sort outperforms bubble sort?

I mean like...partial, full or reverse sorted arrays.
I have already tried the following: random, fully sorted, almost sorted, partially sorted, rever sorted and the count of bubble is lesser when it's fully sorted. In all other cases, it's the same.
int selectionSort(int a[], int l, int r) {
int count = 0;
for (int i = l; i < r; i++) {
int min = i;
for (int j = i + 1; j <= r; j++) {
if (a[j] < a[min]) min = j;
count++;
}
if (i != min) swap(a[i], a[min]);
}
return count;
}
int bubbleSort(int a[], int l, int r) {
int count = 0;
bool flag = false;
for (int i = l; i < r; i++) {
for (int j = r; j > i; j--) {
if (a[j-1] > a[j]) {
if (flag == false) flag = true;
swap(a[j - 1], a[j]);
}
count++;
}
if (flag == false) break;
}
return count;
}
The count returns the number of comparisons BTW.
Among simple average-case Θ(n2) algorithms, selection sort almost always outperforms bubble sort.
Source: Wikipedia
I hinted at this already in comments, but here's some updated code for you that counts both comparisons and exchanges/swaps, and illustrates that for some random input the number of exchanges/swaps is where selection sort outperforms bubble sort.
#include <iostream>
#include <vector>
#include <utility>
#include <cassert>
using namespace std;
struct Stats { int swaps_ = 0, compares_ = 0; };
std::ostream& operator<<(std::ostream& os, const Stats& s)
{
return os << "{ swaps " << s.swaps_
<< ", compares " << s.compares_ << " }";
}
Stats selectionSort(std::vector<int>& a, int l, int r) {
Stats stats;
for (int i = l; i < r; i++) {
int min = i;
for (int j = i + 1; j <= r; j++) {
if (a.at(j) < a.at(min)) min = j;
++stats.compares_;
}
if (i != min) {
swap(a.at(i), a.at(min));
++stats.swaps_;
}
}
return stats;
}
Stats bubbleSort(std::vector<int>& a, int l, int r) {
Stats stats;
bool flag = false;
for (int i = l; i < r; i++) {
for (int j = r; j > i; j--) {
if (a.at(j-1) > a.at(j)) {
if (flag == false) flag = true;
swap(a.at(j - 1), a.at(j));
++stats.swaps_;
}
++stats.compares_;
}
if (flag == false) break;
}
return stats;
}
int main()
{
std::vector<int> v1{ 4, 8, 3, 8, 10, -1, 3, 20, 5 };
std::vector<int> v1s = v1;
std::cout << "sel " << selectionSort(v1s, 0, v1s.size() - 1);
std::vector<int> v1b = v1;
std::cout << ", bub " << bubbleSort(v1b, 0, v1b.size() - 1) << '\n';
assert(v1s == v1b);
// always a good idea to check the code's doing what you expect...
for (int i : v1s) std::cout << i << ' ';
std::cout << '\n';
}
Output:
sel { swaps 6, compares 36 }, bub { swaps 15, compares 36 }
-1 3 3 4 5 8 8 10 20
You can observe / copy / fork-and-edit / run the code online here.

MSVC Debugger tells me that my vector has more positions than specified

I have declared the following:
const int NUMBER_OF_DIGITS = 16;
std::vector<int> digits(NUMBER_OF_DIGITS);
However when I open the MSVC debugger it shows the following:
This is how I added values to the vector:
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
scanf("%d", &digits[i]);
}
Is this normal? Can I just ignore this? Or is this a problem?
Full code(the program is still not ready yet):
#include <iostream>
#include <vector>
#include "stdio.h"
const int NUMBER_OF_DIGITS = 16;
int checksum, tmp1, tmp2, tmp3, sum = 0;
std::vector<int> digits(NUMBER_OF_DIGITS);
std::vector<int> new_digits(NUMBER_OF_DIGITS);
int luhn_checksum(std::vector<int> cardnumber[NUMBER_OF_DIGITS]) {
//step 1: duouble every second number
for (int i = 1; i < NUMBER_OF_DIGITS; i += 2) {
new_digits[i] = digits[i] * 2;
if (new_digits[i] > 9) {
//if the product is larger than 9 we will add the two numbers together
//example: 9 * 2 = 18 so we will add 1 + 8 to get 9
tmp1 += new_digits[i] % 10;
new_digits[i] /= 10;
tmp1 = 0;
}
}
//step 2: sum all the values
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
checksum += new_digits[i];
}
return checksum;
}
void get_card_numbers(void) {
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
scanf("%d", &digits[i]);
}
}
void initialize(void) {
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
digits.push_back(0);
new_digits.push_back(0);
}
}
int main() {
initialize();
get_card_numbers();
printf("checksum is: %d\n", luhn_checksum(&digits));
std::cout << digits.size() << std::endl;
int x; scanf("%d", &x);
return 0;
}
The constructor you're using for digits is setting the size by specifying the count. So after calling push_back you've just added another 16 to the vector. Use a different constructor that doesn't set the count.
int _tmain(int argc, _TCHAR* argv[])
{
const int NUMBER_OF_DIGITS = 16;
std::vector<int> digits(NUMBER_OF_DIGITS);
//std::vector<int> digits;
int digitsLen = digits.size();
// Here is 16
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
digits.push_back(0);
}
int digitsLen2 = digits.size();
// Here is 32
return 0;
}
Cleaned up your code a bit:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
static const size_t NUMBER_OF_DIGITS = 16;
class cards {
public:
cards();
void read();
int luhnChecksum() const;
private:
vector<int> digits;
};
cards::cards() : digits(NUMBER_OF_DIGITS, 0)
{
}
void cards::read() {
for_each(digits.begin(), digits.end(), [](int& i) { cin >> i; });
}
int cards::luhnChecksum() const {
vector<int> newdigits(digits.begin(), digits.end());
for (size_t i=1; i<NUMBER_OF_DIGITS; i += 2) {
newdigits[i] = digits[i] * 2;
if (newdigits[i] > 9) {
int tmp1 = newdigits[i] % 10;
newdigits[i] /= 10;
newdigits[i] += tmp1;
}
}
return accumulate(newdigits.begin(), newdigits.end(), 0);
}
int main() {
cards c;
c.read();
cout << "checksum = " << c.luhnChecksum() << endl;
return 0;
}

Querying for a value that's bigger than X, while having another condition

I have list of pair [x;y] where x is unique and y can be duplicate(integers).
Here lies a problem:
Given a pair [x;y], find new pair [k;m], such that:
k > x
m >= y
k - x is minimized.
Now, I've solved this problem with this logic; I sort pairs by x, and then start naive O(n^2) algorithm on it. It seems to work fine, except it's too slow.
Can I do better?
The actual problem im trying to solve, is here: http://www.spoj.com/problems/VBOSS/
and my current code:
#include <stdio.h>
#include <utility>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
struct employee
{
int id;
int salary;
int height;
int parent_index;
int sub_ordinates;
int cur;
bool important;
bool operator < (const employee& e) const
{
if(height == e.height)
return salary > e.salary;
return (height > e.height);
}
};
// problem states explictly that no two employees
// have same salary.
struct salary_predicate
{
inline bool operator() (const employee& struct1, const employee& struct2)
{
return (struct1.salary > struct2.salary);
}
};
const int MAX_EMPLOYEES = 30000;
const int MAX_QUERIES = 200;
employee employees[MAX_EMPLOYEES];
int queries[MAX_QUERIES];
int main()
{
int test_cases;
scanf("%d", &test_cases);
while(test_cases--)
{
int employeeCount, queryCount;
scanf("%d %d", &employeeCount, &queryCount);
int i = 0;
int j = 0;
while(i < employeeCount)
{
employees[i].parent_index = -1;
employees[i].sub_ordinates = 0;
employees[i].cur = i;
employees[i].important = false;
scanf("%d %d %d", &employees[i].id, &employees[i].salary, &employees[i].height);
i++;
}
map<int, int> mapper;
while(j < queryCount)
{
scanf("%d", &queries[j]);
mapper.insert(pair<int, int>(queries[j], -1));
j++;
}
// now step1; sort employees structure
// based on SALARY!!
sort(employees, employees + employeeCount, salary_predicate());
for(int k = 0; k < employeeCount; k++)
{
employees[k].cur = k;
if(mapper.find(employees[k].id) != mapper.end())
{
mapper[employees[k].id] = k;
employees[k].important = true;
}
}
int found = 0;
for(int l = employeeCount - 1; l >= 0; l--)
{
int gef = l - 1;
// check out information about previous worker,
// he might give us some valuable information!
// with his help, we know if we can skip some shit :)
if(l + 1 < employeeCount && employees[l + 1].parent_index != -1)
{
// if previous employee is smaller than our current employee
// then we can skip some people, becase we know that answer cant be
// smalle than that :)
if(employees[l + 1].height <= employees[l].height)
gef = employees[l + 1].parent_index - 1;
}
// find boss!
for(int b = gef; b >= 0; b--)
{
if(employees[b].height >= employees[l].height)
{
employees[l].parent_index = b;
employees[b].sub_ordinates += employees[l].sub_ordinates + 1;
break;
}
}
// this bit makes sure if we have processed all necessay things,
// then we can basically stop our work.
if(employees[l].important) found++;
if(found == mapper.size()) break;
}
// time to print it out.
for(int b = 0; b < queryCount; b++)
{
int id = queries[b];
int index = mapper[id];
int parent_index = employees[index].parent_index;
int parent = parent_index < 0 ? 0 : employees[parent_index].id;
printf("%d %d\r\n", parent, employees[index].sub_ordinates);
}
}
return 0;
}
salary=x, and height=y.
I would start by eliminating all records where m<y or k<=x. Then find the item with the smallest k value out of what's left. Both of these should be linear, so your overall complexity should also be linear.
struct p {
int k, m;
};
p find_item(p xy, std::vector<p> &values) {
auto end = std::partition(values.begin(), values.end(),
[xy](p const &v) { return xy.k < v.k || xy.m >= v.m; });
return *std::min_element(values.begin(), end,
[](p const &a, p const &b) { return a.k < b.k; });
}

Sieve of Eratosthenes algorithm

I am currently reading "Programming: Principles and Practice Using C++", in Chapter 4 there is an exercise in which:
I need to make a program to calculate prime numbers between 1 and 100 using the Sieve of Eratosthenes algorithm.
This is the program I came up with:
#include <vector>
#include <iostream>
using namespace std;
//finds prime numbers using Sieve of Eratosthenes algorithm
vector<int> calc_primes(const int max);
int main()
{
const int max = 100;
vector<int> primes = calc_primes(max);
for(int i = 0; i < primes.size(); i++)
{
if(primes[i] != 0)
cout<<primes[i]<<endl;
}
return 0;
}
vector<int> calc_primes(const int max)
{
vector<int> primes;
for(int i = 2; i < max; i++)
{
primes.push_back(i);
}
for(int i = 0; i < primes.size(); i++)
{
if(!(primes[i] % 2) && primes[i] != 2)
primes[i] = 0;
else if(!(primes[i] % 3) && primes[i] != 3)
primes[i]= 0;
else if(!(primes[i] % 5) && primes[i] != 5)
primes[i]= 0;
else if(!(primes[i] % 7) && primes[i] != 7)
primes[i]= 0;
}
return primes;
}
Not the best or fastest, but I am still early in the book and don't know much about C++.
Now the problem, until max is not bigger than 500 all the values print on the console, if max > 500 not everything gets printed.
Am I doing something wrong?
P.S.: Also any constructive criticism would be greatly appreciated.
I have no idea why you're not getting all the output, as it looks like you should get everything. What output are you missing?
The sieve is implemented wrongly. Something like
vector<int> sieve;
vector<int> primes;
for (int i = 1; i < max + 1; ++i)
sieve.push_back(i); // you'll learn more efficient ways to handle this later
sieve[0]=0;
for (int i = 2; i < max + 1; ++i) { // there are lots of brace styles, this is mine
if (sieve[i-1] != 0) {
primes.push_back(sieve[i-1]);
for (int j = 2 * sieve[i-1]; j < max + 1; j += sieve[i-1]) {
sieve[j-1] = 0;
}
}
}
would implement the sieve. (Code above written off the top of my head; not guaranteed to work or even compile. I don't think it's got anything not covered by the end of chapter 4.)
Return primes as usual, and print out the entire contents.
Think of the sieve as a set.
Go through the set in order. For each value in thesive remove all numbers that are divisable by it.
#include <set>
#include <algorithm>
#include <iterator>
#include <iostream>
typedef std::set<int> Sieve;
int main()
{
static int const max = 100;
Sieve sieve;
for(int loop=2;loop < max;++loop)
{
sieve.insert(loop);
}
// A set is ordered.
// So going from beginning to end will give all the values in order.
for(Sieve::iterator loop = sieve.begin();loop != sieve.end();++loop)
{
// prime is the next item in the set
// It has not been deleted so it must be prime.
int prime = *loop;
// deleter will iterate over all the items from
// here to the end of the sieve and remove any
// that are divisable be this prime.
Sieve::iterator deleter = loop;
++deleter;
while(deleter != sieve.end())
{
if (((*deleter) % prime) == 0)
{
// If it is exactly divasable then it is not a prime
// So delete it from the sieve. Note the use of post
// increment here. This increments deleter but returns
// the old value to be used in the erase method.
sieve.erase(deleter++);
}
else
{
// Otherwise just increment the deleter.
++deleter;
}
}
}
// This copies all the values left in the sieve to the output.
// i.e. It prints all the primes.
std::copy(sieve.begin(),sieve.end(),std::ostream_iterator<int>(std::cout,"\n"));
}
From Algorithms and Data Structures:
void runEratosthenesSieve(int upperBound) {
int upperBoundSquareRoot = (int)sqrt((double)upperBound);
bool *isComposite = new bool[upperBound + 1];
memset(isComposite, 0, sizeof(bool) * (upperBound + 1));
for (int m = 2; m <= upperBoundSquareRoot; m++) {
if (!isComposite[m]) {
cout << m << " ";
for (int k = m * m; k <= upperBound; k += m)
isComposite[k] = true;
}
}
for (int m = upperBoundSquareRoot; m <= upperBound; m++)
if (!isComposite[m])
cout << m << " ";
delete [] isComposite;
}
Interestingly, nobody seems to have answered your question about the output problem. I don't see anything in the code that should effect the output depending on the value of max.
For what it's worth, on my Mac, I get all the output. It's wrong of course, since the algorithm isn't correct, but I do get all the output. You don't mention what platform you're running on, which might be useful if you continue to have output problems.
Here's a version of your code, minimally modified to follow the actual Sieve algorithm.
#include <vector>
#include <iostream>
using namespace std;
//finds prime numbers using Sieve of Eratosthenes algorithm
vector<int> calc_primes(const int max);
int main()
{
const int max = 100;
vector<int> primes = calc_primes(max);
for(int i = 0; i < primes.size(); i++)
{
if(primes[i] != 0)
cout<<primes[i]<<endl;
}
return 0;
}
vector<int> calc_primes(const int max)
{
vector<int> primes;
// fill vector with candidates
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;
}
In the code fragment below, the numbers are filtered before they are inserted into the vector. The divisors come from the vector.
I'm also passing the vector by reference. This means that the huge vector won't be copied from the function to the caller. (Large chunks of memory take long times to copy)
vector<unsigned int> primes;
void calc_primes(vector<unsigned int>& primes, const unsigned int MAX)
{
// If MAX is less than 2, return an empty vector
// because 2 is the first prime and can't be placed in the vector.
if (MAX < 2)
{
return;
}
// 2 is the initial and unusual prime, so enter it without calculations.
primes.push_back(2);
for (unsigned int number = 3; number < MAX; number += 2)
{
bool is_prime = true;
for (unsigned int index = 0; index < primes.size(); ++index)
{
if ((number % primes[k]) == 0)
{
is_prime = false;
break;
}
}
if (is_prime)
{
primes.push_back(number);
}
}
}
This not the most efficient algorithm, but it follows the Sieve algorithm.
below is my version which basically uses a bit vector of bool and then goes through the odd numbers and a fast add to find multiples to set to false. In the end a vector is constructed and returned to the client of the prime values.
std::vector<int> getSieveOfEratosthenes ( int max )
{
std::vector<bool> primes(max, true);
int sz = primes.size();
for ( int i = 3; i < sz ; i+=2 )
if ( primes[i] )
for ( int j = i * i; j < sz; j+=i)
primes[j] = false;
std::vector<int> ret;
ret.reserve(primes.size());
ret.push_back(2);
for ( int i = 3; i < sz; i+=2 )
if ( primes[i] )
ret.push_back(i);
return ret;
}
Here is a concise, well explained implementation using bool type:
#include <iostream>
#include <cmath>
void find_primes(bool[], unsigned int);
void print_primes(bool [], unsigned int);
//=========================================================================
int main()
{
const unsigned int max = 100;
bool sieve[max];
find_primes(sieve, max);
print_primes(sieve, max);
}
//=========================================================================
/*
Function: find_primes()
Use: find_primes(bool_array, size_of_array);
It marks all the prime numbers till the
number: size_of_array, in the form of the
indexes of the array with value: true.
It implemenets the Sieve of Eratosthenes,
consisted of:
a loop through the first "sqrt(size_of_array)"
numbers starting from the first prime (2).
a loop through all the indexes < size_of_array,
marking the ones satisfying the relation i^2 + n * i
as false, i.e. composite numbers, where i - known prime
number starting from 2.
*/
void find_primes(bool sieve[], unsigned int size)
{
// by definition 0 and 1 are not prime numbers
sieve[0] = false;
sieve[1] = false;
// all numbers <= max are potential candidates for primes
for (unsigned int i = 2; i <= size; ++i)
{
sieve[i] = true;
}
// loop through the first prime numbers < sqrt(max) (suggested by the algorithm)
unsigned int first_prime = 2;
for (unsigned int i = first_prime; i <= std::sqrt(double(size)); ++i)
{
// find multiples of primes till < max
if (sieve[i] = true)
{
// mark as composite: i^2 + n * i
for (unsigned int j = i * i; j <= size; j += i)
{
sieve[j] = false;
}
}
}
}
/*
Function: print_primes()
Use: print_primes(bool_array, size_of_array);
It prints all the prime numbers,
i.e. the indexes with value: true.
*/
void print_primes(bool sieve[], unsigned int size)
{
// all the indexes of the array marked as true are primes
for (unsigned int i = 0; i <= size; ++i)
{
if (sieve[i] == true)
{
std::cout << i <<" ";
}
}
}
covering the array case. A std::vector implementation will include minor changes such as reducing the functions to one parameter, through which the vector is passed by reference and the loops will use the vector size() member function instead of the reduced parameter.
Here is a more efficient version for Sieve of Eratosthenes algorithm that I implemented.
#include <iostream>
#include <cmath>
#include <set>
using namespace std;
void sieve(int n){
set<int> primes;
primes.insert(2);
for(int i=3; i<=n ; i+=2){
primes.insert(i);
}
int p=*primes.begin();
cout<<p<<"\n";
primes.erase(p);
int maxRoot = sqrt(*(primes.rbegin()));
while(primes.size()>0){
if(p>maxRoot){
while(primes.size()>0){
p=*primes.begin();
cout<<p<<"\n";
primes.erase(p);
}
break;
}
int i=p*p;
int temp = (*(primes.rbegin()));
while(i<=temp){
primes.erase(i);
i+=p;
i+=p;
}
p=*primes.begin();
cout<<p<<"\n";
primes.erase(p);
}
}
int main(){
int n;
n = 1000000;
sieve(n);
return 0;
}
Here's my implementation not sure if 100% correct though :
http://pastebin.com/M2R2J72d
#include<iostream>
#include <stdlib.h>
using namespace std;
void listPrimes(int x);
int main() {
listPrimes(5000);
}
void listPrimes(int x) {
bool *not_prime = new bool[x];
unsigned j = 0, i = 0;
for (i = 0; i <= x; i++) {
if (i < 2) {
not_prime[i] = true;
} else if (i % 2 == 0 && i != 2) {
not_prime[i] = true;
}
}
while (j <= x) {
for (i = j; i <= x; i++) {
if (!not_prime[i]) {
j = i;
break;
}
}
for (i = (j * 2); i <= x; i += j) {
not_prime[i] = true;
}
j++;
}
for ( i = 0; i <= x; i++) {
if (!not_prime[i])
cout << i << ' ';
}
return;
}
I am following the same book now. I have come up with the following implementation of the algorithm.
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
inline void keep_window_open() { char ch; cin>>ch; }
int main ()
{
int max_no = 100;
vector <int> numbers (max_no - 1);
iota(numbers.begin(), numbers.end(), 2);
for (unsigned int ind = 0; ind < numbers.size(); ++ind)
{
for (unsigned int index = ind+1; index < numbers.size(); ++index)
{
if (numbers[index] % numbers[ind] == 0)
{
numbers.erase(numbers.begin() + index);
}
}
}
cout << "The primes are\n";
for (int primes: numbers)
{
cout << primes << '\n';
}
}
Here is my version:
#include "std_lib_facilities.h"
//helper function:check an int prime, x assumed positive.
bool check_prime(int x) {
bool check_result = true;
for (int i = 2; i < x; ++i){
if (x%i == 0){
check_result = false;
break;
}
}
return check_result;
}
//helper function:return the largest prime smaller than n(>=2).
int near_prime(int n) {
for (int i = n; i > 0; --i) {
if (check_prime(i)) { return i; break; }
}
}
vector<int> sieve_primes(int max_limit) {
vector<int> num;
vector<int> primes;
int stop = near_prime(max_limit);
for (int i = 2; i < max_limit+1; ++i) { num.push_back(i); }
int step = 2;
primes.push_back(2);
//stop when finding the last prime
while (step!=stop){
for (int i = step; i < max_limit+1; i+=step) {num[i-2] = 0; }
//the multiples set to 0, the first none zero element is a prime also step
for (int j = step; j < max_limit+1; ++j) {
if (num[j-2] != 0) { step = num[j-2]; break; }
}
primes.push_back(step);
}
return primes;
}
int main() {
int max_limit = 1000000;
vector<int> primes = sieve_primes(max_limit);
for (int i = 0; i < primes.size(); ++i) {
cout << primes[i] << ',';
}
}
Here is a classic method for doing this,
int main()
{
int max = 500;
vector<int> array(max); // vector of max numbers, initialized to default value 0
for (int i = 2; i < array.size(); ++ i) // loop for rang of numbers from 2 to max
{
// initialize j as a composite number; increment in consecutive composite numbers
for (int j = i * i; j < array.size(); j +=i)
array[j] = 1; // assign j to array[index] with value 1
}
for (int i = 2; i < array.size(); ++ i) // loop for rang of numbers from 2 to max
if (array[i] == 0) // array[index] with value 0 is a prime number
cout << i << '\n'; // get array[index] with value 0
return 0;
}
I think im late to this party but im reading the same book as you, this is the solution in came up with! Feel free to make suggestions (you or any!), for what im seeing here a couple of us extracted the operation to know if a number is multiple of another to a function.
#include "../../std_lib_facilities.h"
bool numIsMultipleOf(int n, int m) {
return n%m == 0;
}
int main() {
vector<int> rawCollection = {};
vector<int> numsToCheck = {2,3,5,7};
// Prepare raw collection
for (int i=2;i<=100;++i) {
rawCollection.push_back(i);
}
// Check multiples
for (int m: numsToCheck) {
vector<int> _temp = {};
for (int n: rawCollection) {
if (!numIsMultipleOf(n,m)||n==m) _temp.push_back(n);
}
rawCollection = _temp;
}
for (int p: rawCollection) {
cout<<"N("<<p<<")"<<" is prime.\n";
}
return 0;
}
Try this code it will be useful to you by using java question bank
import java.io.*;
class Sieve
{
public static void main(String[] args) throws IOException
{
int n = 0, primeCounter = 0;
double sqrt = 0;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println(“Enter the n value : ”);
n = Integer.parseInt(br.readLine());
sqrt = Math.sqrt(n);
boolean[] prime = new boolean[n];
System.out.println(“\n\nThe primes upto ” + n + ” are : ”);
for (int i = 2; i<n; i++)
{
prime[i] = true;
}
for (int i = 2; i <= sqrt; i++)
{
for (int j = i * 2; j<n; j += i)
{
prime[j] = false;
}
}
for (int i = 0; i<prime.length; i++)
{
if (prime[i])
{
primeCounter++;
System.out.print(i + ” “);
}
}
prime = new boolean[0];
}
}