C++ sieve of Eratosthenes with array [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'd like to code the famous Sieve of Eratosthenes in C++ using just array as it would be a set where I can delete some elements on the way to find out primes numbers.
I don't want to use STL (vector, set)... Just array! How can I realize it?
I try to explain why I don't want to use STL set operator: I'm learning C++ from the very beginning and I think STL is of course useful for programmers but built on standard library, so I'd like to use former operators and commands. I know that everything could be easier with STL.

The key to the sieve of Eratosthenes's efficiency is that it does not, repeat not, delete ⁄ remove ⁄ throw away ⁄ etc. the composites as it enumerates them, but instead just marks them as such.
Keeping all the numbers preserves our ability to use a number's value as its address in this array and thus directly address it: array[n]. This is what makes the sieve's enumeration and marking off of each prime's multiples efficient, when implemented on modern random-access memory computers (just as with the integer sorting algorithms).
To make that array simulate a set, we give each entry two possible values, flags: on and off, prime or composite, 1 or 0. Yes, we actually only need one bit, not byte, to represent each number in the sieve array, provided we do not remove any of them while working on it.
And btw, vector<bool> is automatically packed, representing bools by bits. Very convenient.

From Algorithms and Data Structures
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
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;
}
int main()
{
runEratosthenesSieve(1000);
}
You don't want to use STL, but that's not a good idea
STL makes life much simpler.
Still consider this implementation using std::map
int max = 100;
S sieve;
for(int it=2;it < max;++it)
sieve.insert(it);
for(S::iterator it = sieve.begin();it != sieve.end();++it)
{
int prime = *it;
S::iterator x = it;
++x;
while(x != sieve.end())
if (((*x) % prime) == 0)
sieve.erase(x++);
else
++x;
}
for(S::iterator it = sieve.begin();it != sieve.end();++it)
std::cout<<*it<<std::endl;

Related

How to find the power of the array elements? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I need to check if A[0] ^ A[1] ^ A[2] ... ^ A[N] is even or odd.
Is this code right??
#include <bits/stdc++.h>
#include <cmath>
using namespace std;
int main(){
long long n;
cin >> n;
int a[n];
long int mp;
for(int i = 0; i < n; i++){
cin >> a[i];
mp = pow(a[i], a[i+1]);
}
if (mp % 2 == 0){
cout << "YES";
}
else cout<<"NO";
}
Do the maths first.
Consider that
odd * odd * odd * odd .... * odd == odd
You can multiply any odd factors and the result is always odd. Whether a number is odd or even is equivalent to: It has a prime factor 2. Some integer raised to some other integer cannot remove a prime factor, it can also not add a prime factor when it wasn't present before. You start with some x and then
x * x * x * x * x .... * x = y
has the same prime factors as x, just with different powers. The only exceptions is to get an odd number from an even one when you raise a number to power 0, because x^0 = 1.
Ergo, you are on the wrong track. Instead of brute force raising numbers to some power you merely need to consider ...
is A[0] odd or even
is any of the other elements 0 (remember that (a^b)^c) is just a^(b*c))
Thats it.
I will not write the code for you to not spoil the exercise. But I should tell you whats wrong with your code: pow is not made to be used with integers. There are many Q&As here about pow returning a "wrong" result, which is most often just due to wrong expectations. Here is one of them: Why does pow(n,2) return 24 when n=5, with my compiler and OS?. Moreover, you are accessing the array out of bounds in the last iteration of the loop. Hence all your code has undefined behavior. Output could be "maybe" or something else entirely. Also, your code merely calculates a[i] ^ a[i+1] and after the loop you only consider the very last result. Thats not what the task you describe asks for. Last but not least, Why aren't variable-length arrays part of the C++ standard?. Use std::vector for dynamically sized arrays.

Lower time complexity of two for loop and optimize this to become 1 for loop [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I want to optimize this loop. Its time complexity is n2. I want something like n or log(n).
for (int i = 1; i <= n; i++) {
for (int j = i+1; j <= n; j++) {
if (a[i] != a[j] && a[a[i]] == a[a[j]]) {
x = 1;
break;
}
}
}
The a[i] satisfy 1 <= a[i] <= n.
This is what I will try :
Let us call B the image by a[], i.e. the set {a[i]}: B = {b[k]; k = 1..K, such that i exists, a[i] = b[k]}
For each b[k] value, k = 1..K, determine the set Ck = {i; a[i] = b[k]}.
Determinate of B and the Ck could be done in linear time.
Then let us examine the sets Ck one by one.
If Card(Ck} = 1 : k++
If Card(Ck) > 1 : if two elements of Ck are elements of B, then x = 1 ; else k++
I will use a table (std::vector<bool>) to memorize if an element of 1..N belongs to B or not.
I hope not having made a mistake. No time to write a programme just now. I could do it later on, but I guess you will be able to do it easily.
Note: I discovered after sending this answer that #Mike Borkland proposed something similar already in a comment...
Since sometimes you need to see a solution to learn, I'm providing you with a small function that does the job you want. I hope it helps.
#define MIN 1
#define MAX 100000 // 10^5
int seek (int *arr, int arr_size)
{
if(arr_size > MAX || arr_size < MIN || MIN < 1)
return 0;
unsigned char seen[arr_size];
unsigned char indices[arr_size];
memset(seen, 0, arr_size);
memset(indices, 0, arr_size);
for(int i = 0; i < arr_size; i++)
{
if (arr[i] <= MAX && arr[i] >= MIN && !indices[arr[i]] && seen[arr[arr[i]]])
return 1;
else
{
seen[arr[arr[i]]] = 1;
indices[arr[i]] = 1;
}
}
return 0;
}
Ok, how and why this works? First, let's take a look at the problem the one the original algorithm is trying to solve; they say half of the solution is a well-stated problem. The problem is to find if in a given integer array A of size n whose elements are bound between one and n ([1,n]) there exist two elements in A, x and y such that x != y and Ax = Ay (the array at the index x and y, respectively). Furthermore, we are seeking for an algorithm with good time complexity so that for n = 10000 the implementation runs within one second.
To begin with, let's start analyzing the problem. In the worst case scenario, the array needs to be completely scanned at least one time to decide if such pair of elements exist within the array. So, we can't do better than O(n). But, how would you do that? One possible way is to scan the array and record if a given index has appeared, this can be done in another array B (of size n); likewise, record if a given number that corresponds to A at the index of the scanned element has appeared, this can also be done in another array C. If while scanning the current element of the array has not appeared as an index and it has appeared as an element, then return yes. I have to say that this is a "classical trick" of using hash-table-like data structures.
The original tasks were: i) to reduce the time complexity (from O(n^2)), and ii) to make sure the implementation runs within a second for an array of size 10000. The proposed algorithm runs in O(n) time and space complexity. I tested with random arrays and it seems the implementation does its job much faster than required.
Edit: My original answer wasn't very useful, thanks for pointing that out. After checking the comments, I figured the code could help a bit.
Edit 2: I also added the explanation on how it works so it might be useful. I hope it helps :)
I want to optimize this loop. Its time complexity is n2. I want something like n or log(n).
Well, the easiest thing is to sort the array first. That's O(n log(n)), and then a linear scan looking for two adjacent elements is also O(n), so the dominant complexity is unchanged at O(n log(n)).
You know how to use std::sort, right? And you know the complexity is O(n log(n))?
And you can figure out how to call std::adjacent_find, and you can see that the complexity must be linear?
The best possible complexity is linear time. This only allows us to make a constant number of linear traversals of the array. That means, if we need some lookup to determine for each element, whether we saw that value before - it needs to be constant time.
Do you know any data structures with constant time insertion and lookups? If so, can you write a simple one-pass loop?
Hint: std::unordered_set is the general solution for constant-time membership tests, and Damien's suggestion of std::vector<bool> is potentially more efficient for your particular case.

Arrays not filling in as expected in C++ [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I just started trying to learn C++ yesterday, and one of my goals for the near future is to make a matrix multiplication function.
Before trying that, I wanted to get a feel of how arrays work, so I made a simple program that is supposed to make two arrays that represent (mathematical) vectors in 3D space and take their dot product. Below is the code that I wrote.
/*Initializing two vectors, v1 and v2*/
int v1[3] = { 0 };
int v2[3] = { 0 };
int sum = 0; //This will become the sum for the dot product
int i=0; //counter for the following loop
for(; i<3; ++i)
v1[i] = v2[i] = i+1; //This should make both vectors equal {1,2,3} at the end of the loop
sum += v1[i]*v2[i]; //Component-wise, performing the dot product operation
std::cout<< sum <<std::endl;
return 0;
When the code is done running, the output is supposed to come out to be 1*1 +2*2 +3*3 = 14
However, the output is actually coming out as 647194768, which doesn't seem to make any sense. I heard from some friends that in C++, if you aren't careful about initializing the arrays, then some crazy stuff happens, but I'm completely dumbfounded how something this simple could mess up so badly.
Could you provide some deeper insight into why this is happening, and what about C++'s logic causes this?
You are accidentally putting the sum += line outside the for loop. This is because you have no braces on the loop. So only the first line v1[i]... is included in the for loop. Change it like this:
/*Initializing two vectors, v1 and v2*/
int v1[3] = { 0 };
int v2[3] = { 0 };
int sum = 0; //This will become the sum for the dot product
for(int i=0; i<3; ++i)
{
v1[i] = v2[i] = i+1; //This should make both vectors equal {1,2,3} at the end of the loop
sum += v1[i]*v2[i]; //Component-wise, performing the dot product operation
}
std::cout<< sum <<std::endl;
return 0;
Note the use of braces { .. } around the for loop statements. Now this gives the correct answer: 14.
As you ask deeper insight here i am writing some explanation of your code
int v1[3] = { 0 };
int v2[3] = { 0 };
Initializing v1 and v2 with 0,
int sum = 0; //This will become the sum for the dot product
Here you Initializing sum with 0 (GOOD)
int i=0; //counter for the following loop
for(; i<3; ++i)
v1[i] = v2[i] = i+1; //This should make both vectors equal {1,2,3} at the end of the loop
sum += v1[i]*v2[i]; //Component-wise, performing the dot product operation
Here you make mistake as you did not provide {..} compiler will consider first list in loop statement. like below
v1[0] = v2[0] = 0+1
v1[1] = v2[1] = 1+1
v1[2] = v2[2] = 2+1
Now second line will come in picture,
Note that now i is become 3.
sum += v1[i]*v2[i];
Here, you try to access invalid location of an array (4th one)
that's the reason why you got 647194768
You got junk value nothing else
Correct code is already given by metacubed, so I am not writing here,
best of luck for you further study.

How to make this code faster (learning best practices)? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have this little loop here, and I was wondering if I do some big mistake, perf wise.
For example, is there a way to rewrite parts of it differently, to make vectorization possible (assuming GCC4.8.1 and all vecotrization friendly flags enabled)?
Is this the best way to pass a list a number (const float name_of_var[])?
The idea of the code is to take a vector (in the mathematical sense, not necesserly a std::vector) of (unsorted numbers) y and two bound values (ox[0]<=ox[1]) and to store in a vector of integers rdx the index i of the entry of y satisfying ox[0]<=y[i]<=ox[1].
rdx can contain m elements and y has capacity n and n>m. If there are more than m
values of y[i] satisfying ox[0]<=y[i]<=ox[1] then the code should return the first m
Thanks in advance,
void foo(const int n,const int m,const float y[],const float ox[],int rdx[]){
int d0,j=0,i=0;
for(;;){
i++;
d0=((y[i]>=ox[0])+(y[i]<=ox[1]))/2;
if(d0==1){
rdx[j]=i;
j++;
}
if(j==m) break;
if(i==n-1) break;
}
}
d0=((y[i]>=ox[0])+(y[i]<=ox[1]))/2;
if(d0==1)
I believe the use of an intermediary variable is useless, and take a few more cycles
This is the most optimized version I could think of, but it's totally unreadable...
void foo(int n, int m, float y[],const float ox[],int rdx[])
{
for(int i = 0; i < n && m != 0; i++)
{
if(*y >= *ox && *y <= ox[1])
{
*rdx=i;
rdx++;
m--;
}
y++;
}
}
I think the following version with a decent optimisation flag should do the job
void foo(int n, int m,const float y[],const float ox[],int rdx[])
{
for(int j = 0, i = 0; j < m && i < n; i++) //Reorder to put the condition with the highest probability to fail first
{
if(y[i] >= ox[0] && y[i] <= ox[1])
{
rdx[j++] = i;
}
}
}
Just to make sure I'm correct: you're trying to find the first m+1 (if it's actually m, do j == m-1) values that are in the range of [ ox[0], ox[1] ]?
If so, wouldn't it be better to do:
for (int i=0, j=0;;++i) {
if (y[i] < ox[0]) continue;
if (y[i] > ox[1]) continue;
rdx[j] = i;
j++;
if (j == m || i == n-1) break;
}
If y[i] is indeed in the range you must perform both comparisons as we both do.
If y[i] is under ox[0], no need to perform the second comparison.
I avoid the use of division.
A. Yes, passing the float array as float[] is not only efficient, it is the only way (and is identical to a float * argument).
A1. But in C++ you can use better types without performance loss. Accessing a vector or array (the standard library container) should not be slower than accessing a plain C style array. I would strongly advise you to use those. In modern C++ there is also the possibility to use iterators and functors; I am no expert there but if you can express the independence of operations on different elements by being more abstract you may give the compiler the chance to generate code that is more suitable for vectorization.
B. You should replace the division by a logical AND, operator&&. The first advantage is that the second condition is not evaluated at all if the first one is false -- this could be your most important performance gain here. The second advantage is expressiveness and thus readability.
C. The intermediate variable d0 will probably disappear when you compile with -O3, but it's unnecessary nonetheless.
The rest is ok performancewise. Idiomatically there is room for improvement as has been shown already.
D. I am not sure about a chance for vectorization with the code as presented here. The compiler will probably do some loop unrolling at -O3; try to let it emit SSE code (cf. http://gcc.gnu.org/onlinedocs/, specifically http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/i386-and-x86-64-Options.html#i386-and-x86-64-Options). Who knows.
Oh, I just realized that your original code passes the constant interval boundaries as an array with 2 elements, ox[]. Since array access is an unnecessary indirection and as such may carry an overhead, using two normal float parameters would be preferred here. Keep them const like your array. You could also name them nicely.

How to check if two n-sized vectors are linearly dependant on C++? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
A program should be made which finds if the two vectors a = (a0, a1, ..., an-1) and b = (b0, b1, ..., bn-1) (1 ≤ n ≤ 20) are linearly dependant. The input should be n, and the coordinates of the two vectors and the output should be 1 if the vectors are linearly dependant, else - 0.
I've been struggling for hours over this now and I've got absolutely nothing. I know only basic C++ stuff and my geometry sucks way too much. I'd be really thankful if someone would write me a solution or at least give me some hint. Thanks in advance !
#include <iostream>
using namespace std;
int main()
{
int n;
double a[20], b[20];
cin >> n;
int counter = n;
bool flag = false;
for (int i = 0; i < n; i++)
{
cin >> a[i];
cin >> b[i];
}
double k;
for (int i = 0; i < n; i++)
{
for (k = 0; k < 1000; k = k + 0.01)
{
if (a[i] == b[i])
{
counter--;
}
}
}
if (counter == 0 && k != 0)
flag = true;
cout << flag;
return 0;
}
Apparently that was all I could possibly come up with. The "for" cycle is wrong on so many levels but I don't know how to fix it. I'm open to suggestions.
There are 4 parts to the problem:
1. Math and algorithms
Vectors a and b are linearly depndent if ∃k. a = k b. That is expanded to ∃k. ∑i=1..n ai = k ai and that is a set of equations any of which can be solved for k.
So you calculate k as b0 / a0 and check that the same k works for the other dimensions.
Don't forget to handle a0 = 0 (or small, see below). I'd probably swap the vectors so the larger absolute value is denominator.
2. Limited precision numeric calculations
Since the precision is limited, calculations involve rounding error. You need to check for approximate equality, not exact, because most likely you won't get exact results even when you expect them.
Approximate equality comes in two forms, absolute (|x - y| < ε) and relative (1 - ε < |x / y| < 1 + ε). Obviously the relative makes more sense here (you want to ignore the last significant digit only), but again you have to handle the case where the values are too small.
3. C++
Don't use plain arrays, use std::vector. That way you won't have arbitrary limits.
Iterate with iterator, not indices. Iterators work for all container types, indices only work for the few with continuous integral indices and random access. Which is basically just vector and plain array. And note that iterators are designed so that pointer is iterator, so you can iterate with iterator over plain arrays too.
4. Plain old bugs
You have the loop over k, but you don't use the value inside the loop.
The logic with counter does not seem to make any sense. I don't even see what you wanted to achieve with that.
You're right, that code bears no reationship to the problem at all.
It's easier than you think (at least conceptually). Divide each element in the vector by the corressponding element in the other vector. If all those division result in the same number then the vectors are linearly dependendent. So { 1, 2, 4 } and { 3, 6, 12 } are linear because 1/3 == 2/6 == 4/12.
However there are two technical problems. First you have to consider what happens when your elements are zero, you don't want to divide by zero.
Secondly because you are dealing with floating point numbers it's not sufficient to test if two numbers are equal. Because of rounding errors they often won't be. So you have to come up with some test to see if two numbers are nearly equal.
I'll leave you to think about both those problems.