Modulo operation vs. Ternary operation - c++

I need to iterate over n pairs of integers: (0, 1), (1, 2), (2, 3) ... (n-2, n-1), (n-1, 0)
What's the best way to do it?
Using modulo operation:
for (int i = 0; i < n; i++){
int a = i;
int b = (i + 1)%n
//MaaaanyLinesOfDoSomethingWithAAndB
}
Using ternary operation:
for (int i = 0; i < n; i++){
int a = i;
int b = (i + 1 == n ? 0 : i + 1)
//MaaaanyLinesOfDoSomethingWithAAndB
}
Or:
for (int i = 0; i < n; i++){
int a = i;
int b = (i + 1 >= n ? 0 : i + 1)
//MaaaanyLinesOfDoSomethingWithAAndB
}
Another idea? Let's assume that there are maaaany lines of do something and it'd look ugly if we do (0, 1), (1, 2), (2, 3) ... (n-2, n-1) part and (n-1, 0) part separately.
Which operation is the most efficient one?
EDIT #1
I'm sorry, I think I haven't asked my question properly. I wanted to know which operator acts faster (in, e.g. seconds or clock ticks). I also decided to make little experiment and just measure it by clock() function. Here's my code:
#include <time.h>
#include <limits.h>
#include <string>
#include <iostream>
using namespace std;
typedef void (*fun) (int a);
void DoSomething(int i){
int a = i;
}
void ModuloOperation (int n){
for (int i = 0; i < n; i++)
DoSomething((i + 1) % n);
}
void TernaryEqual (int n){
for (int i = 0; i < n; i++)
DoSomething(i + 1 == n ? 0 : i + 1);
}
void TernaryBiggerEqual (int n){
for (int i = 0; i < n; i++)
DoSomething(i + 1 >= n ? 0 : i + 1);
}
void SplitIntoTwoParts (int n){
for (int i = 0; i < n - 1; i++)
DoSomething(i + 1);
DoSomething(n - 1);
}
int main(){
const int n = INT_MAX;
string testNames[] = {
"Modulo",
"Trenary equal",
"Trenary bigger equal",
"Split into two parts"
};
fun tests[] = {
ModuloOperation,
TernaryEqual,
TernaryBiggerEqual,
SplitIntoTwoParts
};
clock_t t;
for (int i = 0; i < sizeof(testNames)/sizeof(testNames[0]); i++){
t = clock();
tests[i](n);
t = clock() - t;
cout<<testNames[i]<<": "<<((float)t)/CLOCKS_PER_SEC<<" seconds\n\n";
}
return 0;
}
And here's an output
Modulo: 53.867 seconds
Trenary equal: 36.684 seconds
Trenary bigger equal: 37.299 seconds
Split into two parts: 31.37 seconds
So it seems that p.s.w.g's idea is not only the cleanest one but also the best one.
And once again, sorry for my mistake, I'm not native speaker, I'm still learning.

You mentioned that it would look ugly if you do the 'maaaany' lines separately. None of the above options are particularly pretty either. So perhaps it's better to encapsulate this ugly logic in a method and use some more elegant code in your loop.
For readability, I'd probably go with this:
for (int i = 0; i < n - 1; i++){
DoStuff(i, i + 1);
}
DoStuff(n - 1, 0);
// elsewhere
void DoStuff(int a, int b)
{
//MaaaanyLinesOfDoSomethingWithAAndB
}
If the 'maaaany' lines require the use of a number local variables and you don't want to pass them all in to the DoStuff method, you might want to consider using a closure, although it wouldn't help the readability of your code nearly as much as proper functional decomposition. Something like this:
Action<int, int> doStuff = (a, b) =>
{
//MaaaanyLinesOfDoSomethingWithAAndB
};
for (int i = 0; i < n - 1; i++){
doStuff(i, i + 1);
}
doStuff(n - 1, 0);
Or perhaps you need to refactor the 'maaaany' lines into a separate worker class, but without knowing more about what's in those lines, it's hard to say.

Related

Interval schedule question about choose the same length of time from each interval

I was struggle with an interval schedule question, the question description as follow:
Description: Lanran has N friends. Every Sunday, Lanran has to play
with his friends. The i-th friend can play with Lanran from time a to
time b (a and b are included). However, Lanran has to play with each
of his friends for the same amount of time. Lanran wants to play with
his friends as long as possible. But he is very stupid. So he asks for
your help to calculate the maximum time he can play with each of his
friends.
Input The first line contains one integer N. Each of the next N (N <=
5000) lines contains two integers a and b (1 <= a, b <= 10000), which
show the time interval of the i-th friend.
Output Output a single integer, shows the maximum time Lanran can play
with each of his friends.
I think this a greedy problem, and I choose the minimal time friend, which is the already played time + possible playing time till b of friend, and play with him at i-th second. Here's the code:
#include <bits/stdc++.h>
using namespace std;
const int N = 5010;
int n, s[N], e[N], cnt[N], me;
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int partition(int low, int high) {
int pivot = s[high];
int i = (low - 1);
for (int j = low; j <= high - 1; j++) {
if (s[j] <= pivot) {
i++;
swap(&s[i], &s[j]);
swap(&e[i], &e[j]);
}
}
swap(&s[i + 1], &s[high]);
swap(&e[i + 1], &e[high]);
return (i + 1);
}
void quickSort(int low, int high) {
if (low < high) {
int pi = partition(low, high);
quickSort(low, pi - 1);
quickSort(pi + 1, high);
}
}
int main() {
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%d%d", &s[i], &e[i]);
if (e[i] < s[i]) { printf("0\n"); return 0; }
if (e[i] > me) me = e[i];
}
quickSort(0, n - 1);
for (int i = 1; i <= me; ++i) {
int id = -1, mi = 0x7fffffff;
for (int j = 0; j < n; ++j) {
if (s[j] > i || i > e[j]) continue;
if (cnt[j] + e[j] - i + 1 < mi) { id = j; mi = cnt[j] + e[j] - i + 1; }
}
++cnt[id];
}
int ans = 0x7fffffff;
for (int i = 0; i < n; ++i) if (cnt[i] < ans) ans = cnt[i];
printf("%d\n", ans);
return 0;
}
So does I make something wrong? I got 7 wrong answer in 10 test cases.
Looks like it is same as standard activity selection problem. I am pasting related standard algorithm. you can find wiki : https://en.wikipedia.org/wiki/Activity_selection_problem.
Greedy-Iterative-Activity-Selector(A, s, f):
Sort A by finish times stored in f
S = {A[1]}
k = 1
n = A.length
for i = 2 to n:
if s[i] ≥ f[k]:
S = S U {A[i]}
k = i
return S

In c++ take an integer array (arr[]), its length (N), and the number of elements to right-shift (M):?

How can I finish my code to take an integer array (arr[]), its length (N), and the number of elements to right-shift (M).
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void shiftright (int myarray[], int size);
int main (void)
{
int myarray [] = {1, 2, 3, 4, 5};
shiftright( myarray, 5);
for ( int i = 0; i < 5; i++)
{
cout << myarray[i] << ' ';
}
return (0);
}
void shiftright (int myarray[], int size, int M)
{
for (int m = (size - 1); m >= 1; m--) {
int temp = myarray[size - 1];
for (int i = (size - 1); i >= 1; i--)
{
myarray[i] = myarray[i - 1] ;
}
myarray[0] = temp;
}
}
Instead of rolling your own, simply use a standard algorithm.
if (m > 0 && size > 0)
std::rotate(myarray, myarray + m % size, myarray + size);
Looks like you're trying to perform a "rotate" operation. Have you considered creating an indexer with an offset and not actually having to rotate anything at all? (This is far less costly.)
Anyways, just remove your outer loop to shift once:
void shiftright (int myarray[], int size)
{
int temp = myarray[size - 1];
for (int i = (size - 1); i >= 1; i--)
{
myarray[i] = myarray[i - 1];
}
myarray[0] = temp;
}
Now, you may create another method to shift m times:
void shiftright (int myarray[], int size, int m)
{
for (int i = 0; i < m; i++)
{
shiftright(myarray, size);
}
}
This is obviously very costly in terms of performance, so you may want to explain what you need this for.

Work out a solution for codality?

A zero-indexed array A consisting of N different integers is given. The array contains integers in the range [1..(N + 1)], which means that exactly one element is missing.
Your goal is to find that missing element.
Write a function:
int solution(int A[], int N);
that, given a zero-indexed array A, returns the value of the missing element.
For example, given array A such that:
A[0] = 2 A[1] = 3 A[2] = 1 A[3] = 5
the function should return 4, as it is the missing element.
Assume that:
N is an integer within the range [0..100,000];
the elements of A are all distinct;
each element of array A is an integer within the range [1..(N + 1)].
Complexity:
expected worst-case time complexity is O(N);
expected worst-case space complexity is O(1), beyond input storage (not counting the storage required for input arguments).
It doesn't work for a case that there are two elements
int solution(vector<int> &A) {
sort(A.begin(), A.end());
int missingIndex = 0;
for (int i = 0; i < A.size(); i++)
{
if ( i != A[i]-1)
{
missingIndex = i+1;
}
}
return missingIndex;
}
Since your array is zero-indexed and the numbers are from 1 to N+1, the statement should be:
if ( i != A[i]-1)
Also, you should immediately break out from the for loop after updating the missingIndex because all entries beyond the missing element shall have (i != A[i]-1)
Moreover because of sorting your solution is O(NlogN) and not O(N).
Instead you can sum all the elements in the array (using unsigned long long int) and check its difference from N(N+1)/2
You can use the simple math formula for an arithmetic progression to get the sum of all numbers from 1 to N+1. Then iterate over all the given numbers and calculate that sum. The missing element will be the difference between the two sums.
int solution(std::vector<int> &a) {
uint64_t sum = (a.size() +1 ) * (a.size() + 2) / 2;
uint64_t actual = 0;
for(int element : a) {
actual += element;
}
return static_cast<int>(sum - actual);
}
Use all the power of STL:
#include <algorithm>
#include <functional>
int solution(vector<int> &A) {
return std::accumulate(A.begin(), A.end(), (A.size()+1) * (A.size()+2) / 2, std::minus<int>());
}
This solution uses the sign of the values as a flag. It needs at worst two pass over the elements. The N(N+1)/2 solution needs exactly one pass.
int solution(vector<int> &a) {
int n = (int)a.size();
for(auto k : a)
{
int i = abs(k) - 1;
if (i != n)
a[i] = -a[i];
}
for (int i = 0; i < n; ++i)
if (a[i]>0)
return i+1;
return n+1;
}
I solved it this way and thought of posting it here for my own reference for future and for others :)
#include <cstdint>
#include <numeric>
int solution(vector<int> &A) {
uint64_t sumAll = (A.size() + 1) * (A.size() + 2) / 2;
uint64_t sumA = std::accumulate(A.begin(), A.end(), 0);
return sumAll- sumA;
}
I solve it with this solution maybe there is something better but I test it with different values and find it work fine while the other solutions gives me strange results.
as example:
std::vector<int> A = { 12,13,11,14,16 };
std::vector<int> A2 = { 112,113,111,114,116 };
int Solution(std::vector<int> &A)
{
int temp;
for (int i = 0; i < A.size(); ++i)
{
for (int j = i+1;j< A.size();++j )
{
if (A[i] > A[j])
{
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
}
for (int i = 0; i < A.size()-1;++i)
{
if ((A[i] + 1 != A[i + 1]))
{
return (A[i] + 1);
}
if(i+1 == A.size() - 1)
return (A[i+1] + 1);
}}
Now Everything fine but if I use the array above with the methods below, I will get wrong values excepts with small numbers <10;
std::vector<int> A = { 12,13,11,14,16 };
int Solution_2(std::vector<int> &A)
{
unsigned int n = A.size() + 1;
long long int estimated = n * (n + 1) / 2;
long long int total = 0;
for (unsigned int i = 0; i < n - 1; i++) total += A[i];
return estimated - total;
}
I will get this result -45.
or this one also the same result if I use array A :
std::vector<int> A = { 12,13,11,14,16 };
int Solution_3(std::vector<int> &A)
{
uint64_t sumAll = (A.size() + 1) * (A.size() + 2) / 2;
uint64_t sumA = std::accumulate(A.begin(), A.end(), 0);
return sumAll - sumA;
}
Hope Someone explains why this happens.

lexicographically smallest string after rotation

I am trying to solve this problem in spoj
I need to find the number of rotations of a given string that will make it lexicographically smallest among all the rotations.
For example:
Original: ama
First rotation: maa
Second rotation: aam This is the lexicographically smallest rotation so the answer is 2.
Here's my code:
string s,tmp;
char ss[100002];
scanf("%s",ss);
s=ss;
tmp=s;
int i,len=s.size(),ans=0,t=0;
for(i=0;i<len;i++)
{
string x=s.substr(i,len-i)+s.substr(0,i);
if(x<tmp)
{
tmp=x;
t=ans;
}
ans++;
}
cout<<t<<endl;
I am getting "Time Limit Exceeded" for this solution. I don't understand what optimizations can be made. How can I increase the speed of my solution?
You can use a modified suffix array. I mean modified because you must not stop on word end.
Here is the code for a similar problem I solved (SA is the suffix array):
//719
//Glass Beads
//Misc;String Matching;Suffix Array;Circular
#include <iostream>
#include <iomanip>
#include <cstring>
#include <string>
#include <cmath>
#define MAX 10050
using namespace std;
int RA[MAX], tempRA[MAX];
int SA[MAX], tempSA[MAX];
int C[MAX];
void suffix_sort(int n, int k) {
memset(C, 0, sizeof C);
for (int i = 0; i < n; i++)
C[RA[(i + k)%n]]++;
int sum = 0;
for (int i = 0; i < max(256, n); i++) {
int t = C[i];
C[i] = sum;
sum += t;
}
for (int i = 0; i < n; i++)
tempSA[C[RA[(SA[i] + k)%n]]++] = SA[i];
memcpy(SA, tempSA, n*sizeof(int));
}
void suffix_array(string &s) {
int n = s.size();
for (int i = 0; i < n; i++)
RA[i] = s[i];
for (int i = 0; i < n; i++)
SA[i] = i;
for (int k = 1; k < n; k *= 2) {
suffix_sort(n, k);
suffix_sort(n, 0);
int r = tempRA[SA[0]] = 0;
for (int i = 1; i < n; i++) {
int s1 = SA[i], s2 = SA[i-1];
bool equal = true;
equal &= RA[s1] == RA[s2];
equal &= RA[(s1+k)%n] == RA[(s2+k)%n];
tempRA[SA[i]] = equal ? r : ++r;
}
memcpy(RA, tempRA, n*sizeof(int));
}
}
int main() {
int tt; cin >> tt;
while(tt--) {
string s; cin >> s;
suffix_array(s);
cout << SA[0]+1 << endl;
}
}
I took this implementation mostly from this book. There is an easier to write O(n log²n) version, but may not be efficient enough for your case (n=10^5). This version is O(n log n), and it's not the most efficient algorithm. The wikipedia article lists some O(n) algorithms, but I find most of them too complex to write during a programming contest. This O(n log n) is usually enough for most problems.
You can find some slides explaining suffix array concept (from the author of the book I mentioned) here.
I know this comes very late but I stumbled across this from google on my search for an even faster variant of this algorithm. Turns out a good implementation is found at github: https://gist.github.com/MaskRay/8803371
It uses the lyndon factorization. That means it repeatly splits the string into lexicographically decreasing lyndon words. Lyndon word are strings that are (one of) the minimal rotations of themselves. Doing this in a circular way yields the lms of the string as the last found lyndon word.
int lyndon_word(const char *a, int n)
{
int i = 0, j = 1, k;
while (j < n) {
// Invariant: i < j and indices in [0,j) \ i cannot be the first optimum
for (k = 0; k < n && a[(i+k)%n] == a[(j+k)%n]; k++);
if (a[(i+k)%n] <= a[(j+k)%n]) {
// if k < n
// foreach p in [j,j+k], s_p > s_{p-(j-i)}
// => [j,j+k] are all suboptimal
// => indices in [0,j+k+1) \ i are suboptimal
// else
// None of [j,j+k] is the first optimum
j += k+1;
} else {
// foreach p in [i,i+k], s_p > s_{p+(j-i)}
// => [i,i+k] are all suboptimal
// => [0,j) and [0,i+k+1) are suboptimal
// if i+k+1 < j
// j < j+1 and indices in [0,j+1) \ j are suboptimal
// else
// i+k+1 < i+k+2 and indices in [0,i+k+2) \ (i+k+1) are suboptimal
i += k+1;
if (i < j)
i = j++;
else
j = i+1;
}
}
// j >= n => [0,n) \ i cannot be the first optimum
return i;
}

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];
}
}