I'm running just a simple code, but I keep getting "Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)"
Doing some debugging, I found that the value of edges[0].start somehow becomes -2147483644. I'm finding this behavior quite hard to explain and still trying to find where did I get it wrong but I don't even update any edges values! Anyways, whatever hints you can give me will be greatly valued. You will find the code bellow.
Thanks in advance!
Warm wishes
#include <stdio.h>
#include <climits>
#include "Utils.h"
struct edge {
int start;
int end;
int weight;
};
int main() {
int n = 4;
int m = 4;
edge edges[4] = {
{2,4,5},
{4,1,6},
{1,3,8},
{3,2,-3}
};
int v,e;
int distance[4];
// Step 1: initialize graph
for(v = 0; v < n; v++){
distance[v] = INT_MAX;
}
distance[0] = 0; //source
// Step 2: relax edges repeatedly
for(v = 0; v < n; v++){
for(e = 0; e < m; e++){
if(distance[edges[e].start] + edges[e].weight < distance[edges[e].end] ){ //relax
distance[edges[e].end] = distance[edges[e].start] + edges[e].weight;
}
}
}
// Step 3: check for negative-weight cycles
for(e = 0; e < m; e++) {
if (distance[edges[e].start] + edges[e].weight < distance[edges[e].end]) { //shouldn't be able to relax
std::cout << "Negative cycle detected, please declare war to Paraguay";
}
}
for(v = 0; v < n; v++){
std::cout << distance[v] << std::endl;
}
return 0;
}
Your 'n' and 'm' iterator variables are defined as 4, yet the 'edges' array has indexes between 0 and 3 inclusive. Your loop will try to access edges[4], resulting in an index out of range and undefined behaviour, which is the likely cause of your start value corruption.
You have defined distance variable with size of 4
int distance[4];
While the values of edge array are:
edge edges[4] = {
{2,4,5},
{4,1,6},
{1,3,8},
{3,2,-3}
};
You are using value of edge structure to access the cell of each distance array.
The value of edge ranges from -3 to 8 while the value of distance ranges from 0 to 3; This will cause the buffer overflow and will cause application to crash.
I'm actually don't know why, but this works for me:
#include <iostream>
struct edge {
int start;
int end;
int weight;
};
int main() {
int n = 4;
int m = 4;
const edge edges[4] = {
{2,4,5},
{4,1,6},
{1,3,8},
{3,2,-3}
}; /* <= for my surprise, I'm not get error with this
* for indexes of distance[something]
*/
int v,e;
int distance[4];
// Step 1: initialize graph
for(v = 0; v < n; v++){
distance[v] = 214748364; // <== with this get fixed
}
distance[0] = 0; //source
// Step 2: relax edges repeatedly
for(v = 0; v < n; v++){
for(e = 0; e < m; e++){
if(distance[edges[e].start] + edges[e].weight < distance[edges[e].end] ){ //relax
distance[edges[e].end] = distance[edges[e].start] + edges[e].weight;
}
}
}
// Step 3: check for negative-weight cycles
for(e = 0; e < m; e++) {
if (distance[edges[e].start] + edges[e].weight < distance[edges[e].end]) { //shouldn't be able to relax
std::cout << "Negative cycle detected, please declare war to Paraguay";
}
}
for(v = 0; v < n; v++){
std::cout << distance[v] << std::endl;
}
return 0;
}
Instead of use distance[v] = INT_MAX; simply use distance[v] = 214748364; or something not so close of INT_MAX and I get this output:
0
8
13
16
Press <RETURN> to close this window...
Related
I am trying to find the solution of lights out game using backtracking method. I am not able to understand the algorithm for this process. My approach is to enumerate all integers from 0 to 2n2 - 1 and For each integer convert it into a binary number which has n*n bits. Then, separate it into n2 binary digits (0 for light off, 1 for light on) and assign them into a n × n grid, for example:
I have written the following code:-
void find_solution(int dest[][MAX_SIZE], int size) {
int y = pow(size,size);
int remainder;
for (int x = 0; x<pow(2,y); x++){
int i = 1;
int binary_number = 0;
int n = x;
while (n!=0) {
remainder = n%2;
n/=2;
binary_number += remainder*i;
i *= 10;
}
int binary_number_digits[size][size];
for (int k = 0; k<size; k++) {
for (int l = 0; l<size; l++) {
binary_number_digits[k][l] = binary_number%10;
binary_number/=10;
}
}
int count = 0;
for (int i = 0; i<size; i++) {
for (int j = 0; j<size; j++) {
if (binary_number_digits[i][j] == dest[i][j]) {
count++;
}
if (count <= 4 && count > 0) {
if (binary_number_digits[i][j] == 1) {
cout << i << j;
}
}
}
}
}
}
I have converted the decimal digits to binary numbers and stored it in an array and checking if they match the randomly generated n*n grid. If it is a 1, it prints that coordinate(x,y). Anyone could please help me solve the problem with this algorithm. Thanks!
The following observations are required (as listed on the Wiki):
In a solution each light has to be pressed at most once. This is because pressing a light an odd number of times is equivalent to pressing it once and pressing a light an even number of times is equivalent to not pressing it.
The order in which the lights are pressed does not matter. This follows from the previous point: Switching a light changes its neighbors, but for the end result of the neighbor it only matters if it was changed an even or odd number of times.
From this we can conclude that we can represent a solution as a 0-1 matrix of the same size as the board, where 1 means that in the solution the light at that position should be pressed. The brute-force algorithm then is to check all nxn 0-1 matrices to see if any of these solves the initial board.
In your implementation, you do the first step (generating all nxn 0-1 matrices that represent ways of pressing the lamps). You are missing the step of checking which of these solve the board.
I would slightly simplify the binary number handling by using std::bitset.
(The following code also requires C++17 for std::optional.)
#include <bitset>
#include <iostream>
#include <optional>
#include <random>
template <size_t N>
class board_t {
public:
void print() const {
for (size_t i = 0; i < data.size(); i++) {
std::cout << data[i];
if (i % N == N - 1) {
std::cout << std::endl;
}
}
}
void randomize() {
std::random_device device;
std::default_random_engine generator{device()};
std::bernoulli_distribution bernoulli(0.5);
for (size_t i = 0; i < data.size(); i++) {
data[i] = bernoulli(generator);
}
}
/**
* Brute-force all possible ways of pressing the lights.
*/
std::optional<board_t<N>> solve() const {
board_t<N> press{};
do {
board_t<N> applied{this->apply(press)};
if (applied.data.none()) {
return press;
}
press.increment();
/**
* Aborts when incrementing press overflows back to the initial
* solution of not pressing any lamp.
*/
} while (press.data.any());
/**
* Return empty std::optional when no solution was found.
*/
return {};
}
private:
/**
* Indicates which lights are on.
*/
std::bitset<N * N> data;
/**
* Interpret the board as a N*N bit binary number and increment it by one.
*/
void increment() {
for (size_t i = 0; i < data.size(); i++) {
if (data[i]) {
data[i] = false;
} else {
data[i] = true;
break;
}
}
}
/**
* Press each light indicated by press.
*/
board_t<N> apply(const board_t<N>& press) const {
board_t<N> copy{*this};
for (size_t y = 0; y < N; y++) {
for (size_t x = 0; x < N; x++) {
size_t offset = x + y * N;
if (press.data[offset]) {
copy.data.flip(offset);
/**
* Check neighbors.
*/
if (x > 0) {
copy.data.flip(offset - 1);
}
if (x < N - 1) {
copy.data.flip(offset + 1);
}
if (y > 0) {
copy.data.flip(offset - N);
}
if (y < N - 1) {
copy.data.flip(offset + N);
}
}
}
}
return copy;
}
};
int main(void) {
constexpr size_t N = 3;
board_t<N> board{};
board.randomize();
board.print();
auto solution{board.solve()};
if (solution) {
std::cout << "Solution:" << std::endl;
solution->print();
} else {
std::cout << "No solution!" << std::endl;
}
return 0;
}
Background:
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
Question:
I have a list of numbers 1,2,3,4,5. My target value is 8, so I should return indices 2 and 4. My first thought is to write a a double for loop that checks to see if adding two elements from the list will get my target value. Although, when checking to see if there is such a solution, my code returns that there is none.
Here is my code:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> list;
list.push_back(1);
list.push_back(2);
list.push_back(3);
list.push_back(4);
list.push_back(5);
int target = 8;
string result;
for(int i = 0; i < list.size(); i++) {
for(int j = i+1; j < list.size(); j++) {
if(list[i] + list[j] == target) {
result = "There is a solution";
}
else {
result = "There is no solution";
}
}
}
cout << result << endl;
return 0;
}
Perhaps my approach/thinking is plain wrong. Could anyone provide any hints or suggestions to solving this problem?
Your approach is correct but you are forgetting you are in a loop that continues after finding the solution.
This will get you halfway there. I recommend putting both loops in a function, and returning once you find a match. One thing you could do is return a pair<int,int> from that function or you could simply output the results from within that point in the loop.
bool solutionFound = false;
int i,j;
for(i = 0; i < list.size(); i++)
{
for(j = i+1; j < list.size(); j++)
{
if(list[i] + list[j] == target)
{
solutionFound = true;
}
}
}
Here is what the function approach might look like:
pair<int, int> findSolution(vector<int> list, int target)
{
for (int i = 0; i < list.size(); i++)
{
for (int j = i + 1; j < list.size(); j++)
{
if (list[i] + list[j] == target)
{
return pair<int, int>(i, j);
}
}
}
return pair<int, int>(-1, -1);
}
int main() {
vector<int> list;
list.push_back(1);
list.push_back(2);
list.push_back(3);
list.push_back(4);
list.push_back(5);
int target = 8;
pair<int, int> results = findSolution(list, target);
cout << results.first << " " << results.second << "\n";
return 0;
}
Here's the C++ incorporating Dave's answer for linear execution time and a couple helpful comments:
pair<int, int> findSolution(vector<int> list, int target)
{
unordered_map<int, int> valueToIndex;
for (int i = 0; i < list.size(); i++)
{
int needed = target - list[i];
auto it = valueToIndex.find(needed);
if (it != valueToIndex.end())
{
return pair<int, int>(it->second, i);
}
valueToIndex.emplace(list[i], i);
}
return pair<int, int>(-1, -1);
}
int main()
{
vector<int> list = { 1,2,3,4,5 };
int target = 10;
pair<int, int> results = findSolution(list, target);
cout << results.first << " " << results.second << "\n";
}
You're doing this in n^2 time. Solve it in linear time by hashing each element, and checking each element to see if it's complement wrt. the total you're trying to achieve is in the hash.
E.g., for 1,2,3,4,5, with a target of 8
indx 0, val 1: 7 isn't in the map; H[1] = 0
indx 1, val 2: 6 isn't in the map, H[2] = 1
indx 2, val 3: 5 isn't in the map, H[3] = 2
indx 3, val 4: 4 isn't in the map, H[4] = 3
indx 4, val 5: 3 is in the map. H[3] = 2. Return 2,4
Code, as requested (Ruby)
def get_indices(arr, target)
value_to_index = {}
arr.each_with_index do |val, index|
if value_to_index.has_key?(target - val)
return [value_to_index[target - val], index]
end
value_to_index[val] = index
end
end
get_indices([1,2,3,4,5], 8)
Basically the same as zzxyz's most recent edit but a little quicker and dirtier.
#include <iostream>
#include <vector>
bool FindSolution(const std::vector<int> &list, // const reference. Less copying
int target)
{
for (int i: list) // Range-based for (added in C++11)
{
for (int j: list)
{
if (i + j == target) // i and j are the numbers from the vector.
// no need for indexing
{
return true;
}
}
}
return false;
}
int main()
{
std::vector<int> list{1,2,3,4,5}; // Uniform initialization Added in C++11.
// No need for push-backs of fixed data
if (FindSolution(list, 8))
{
std::cout << "There is a solution\n";
}
else
{
std::cout << "There is no solution\n";
}
return 0;
}
Full disclosure: this is for an online course.
The code calculates the distances between a starting node in a graph and all other nodes using the Bellman-Ford algorithm. The graph may contain negative cycles: in that case, the output should represent that distance with '-'. If there is no link between the starting node and another node it should '*'. Else, it should output the distance.
The code is working but I believe there is an overflow issue which I don't know how to solve. The constraints specify the following max values:
Nodes: 10^3;
Edges: 10^4;
Edge weights: 10^9
Testing for all logic-related corner cases led to no issues, everything was working correctly. The test this is failing is (most probably) related to overflow.
The code
void bfs(vector<vector<int> > &adj, queue<int> q, vector<bool> &shortest) {
int size = adj.size();
vector<bool> visited(size, false);
while (!q.empty()) {
int v = q.front();
if (visited[v]) {
q.pop();
} else {
q.pop();
for (int i = 0; i < adj[v].size(); i++) {
shortest[adj[v][i]] = true;
q.push(adj[v][i]);
}
}
visited[v] = true;
}
}
void shortest_paths(vector<vector<int> > &adj, vector<vector<int> > &cost, int s,
vector<double> &distance, vector<bool> &reachable, vector<bool> &shortest) {
int size = adj.size();
distance[s] = 0;
reachable[s] = true;
queue<int> negative_cycle;
// Set initial distances and get negative cycles
for (int i = 0; i <= size; i++) {
for (int j = 0; j < size; j++) {
for (int k = 0; k < adj[j].size(); k++) {
// Edge relaxation
if (distance[adj[j][k]] > distance[j] + cost[j][k]) {
reachable[adj[j][k]] = true;
if (i == size) {
// Store negative cycles
negative_cycle.push(adj[j][k]);
shortest[adj[j][k]] = true;
}
distance[adj[j][k]] = distance[j] + cost[j][k];
}
}
}
}
bfs(adj, negative_cycle, shortest);
}
and the main
int main() {
int n, m, s;
std::cin >> n >> m;
vector<vector<int> > adj(n, vector<int>());
vector<vector<int> > cost(n, vector<int>());
for (int i = 0; i < m; i++) {
double x, y, w;
std::cin >> x >> y >> w;
adj[x - 1].push_back(y - 1);
cost[x - 1].push_back(w);
}
std::cin >> s;
s--;
vector<double> distance(n, std::numeric_limits<double>::infinity());
vector<bool> reachable(n, false);
vector<bool> shortest(n, false);
shortest_paths(adj, cost, s, distance, reachable, shortest);
for (int i = 0; i < n; i++) {
if (!reachable[i]) {
std::cout << "*\n";
} else if (shortest[i]) {
std::cout << "-\n";
} else {
std::cout << distance[i] << "\n";
}
}
}
I'm using double and infinity since that is needed for the algorithm (you can read about it here). From the googling I've done, I get this shouldn't overflow since the max possible distance would be 10^4 * 10^9 = 10^13 which is still within double's span. I don't have much experience using infinity or doubles like this, and from what I've researched I couldn't trace the problem.
Is there an alternative to using double infinity (since long longdoesn't have it and it's max_size cannot be used in the context of the problem)? Can there be a double overflow in this case or other issues related (comparison failures, etc)?
I am new in C++. I am trying to compute the path to travel from node start to node end using Dijkstra algorithm. I am pretty sure I am computing the shortest path in the correct way but for some reason I can't store it in my traceBack vector. It would be really helpful if anyone would help me pointing my mistake here.
My function descriptions and the part of the code where I am computing the shortest path is the following:
The function find_connected_nodes(int x) returns only the nodes connected to the given node.
the function find_travel_time(int x, int y) returns the time to travel from x to y.
void dijkstra(int start, int end) {
vector <unsigned> visited(getNumberOfNodes(), 0);
vector <double> time_weight(getNumberOfNodes(), 99999); //99999 to represent not connected
int inNode = start, pathNode = _end, nextnode = 0;
double min; //will use min to compare time between edges
vector<unsigned> traceBack(getNumberOfNodes(), inNode); //traceBack to contain the path from start to end
time_weight[inNode] = 0;
visited[inNode] = 1;
vector<unsigned> x = find_connected_nodes(start);
if (!x.empty()) {
for (unsigned i = 0; i < x.size(); i++) {
time_weight[x[i]] = find_travel_time(start, x[i]));
}
}
for (int i = 0; i < getNumberOfNodes(); i++) {
min = 99999;
for (int j = 0; j < x.size(); j++) {
if (min > time_weight[x[j]] && visited[x[j]] != 1) {
min = time_weight[x[j]];
nextnode = x[j];
}
}
visited[nextnode] = 1;
for (int j = 0; j < x.size(); j++) {
if (visited[x[j]] != 1) {
if (min + find_travel_time(nextnode, x[j]))<time_weight[x[j]]) {
time_weight[x[j]] = min + find_travel_time(nextnode, x[j]));
traceBack[x[j]] = nextnode;
}
}
}
x = find_connected_nodes(nextnode);
}
int j;
cout << "Path = " << pathNode;
j = pathNode;
do {
j = traceBack[j];
cout << "<-" << j;
} while (j != inNode);
}
Not a complete solution to your problem, because it’s homework and you’ll want to solve it on your own, but here is an example of how to solve the same kind of design problem you’re dealing with:
#include <cstdlib>
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::size_t;
std::vector<double> map_squares( const std::vector<double>& inputs )
/* Maps the square function onto the inputs. That is, returns a vector whose
* elements are the squares of the input elements.
*/
{
const size_t size = inputs.size(); // The number of inputs, and outputs.
std::vector<double> outputs(size); // We will return this.
/* (Actually, we will return a copy of the vector, and then the compiler will
* optimize the copy so it doesn't have to copy every element, just a single
* reference to the data in the vector. You'll learn more about how that
* works, and how to write classes like that yourself, in due time.)
*/
for ( size_t i = 0; i < size; ++i ) {
outputs[i] = inputs[i]*inputs[i];
}
outputs.shrink_to_fit(); // Maybe save a few bytes of memory.
return outputs;
}
std::ostream& operator<<( std::ostream& os, const std::vector<double>& v )
// Boilerplate to serialize and print a vector to a stream.
{
const size_t size = v.size();
os << '[';
if (size > 0)
os << v[0];
for ( size_t i = 1; i < size; ++i )
os << ',' << v[i];
os << ']';
return os;
}
int main(void)
{
// Out inputs:
const std::vector<double> raw_numbers = {4,2,1,0.5,0.25};
// Our results:
const std::vector<double> squares = map_squares(raw_numbers);
// Output: "[16,4,1,0.25,0.0625]"
cout << squares << endl;
return EXIT_SUCCESS;
}
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];
}
}