I need to use two loops in such a way that the outer loop drives the inner loop to do computations for 2,4,8,16,and 32 iterations.
for example if i=2(for outer loop)
then inner loop will iterate for 4 times
and if i=3
then inner loop will iterate for 8 times and so on.
this is the logic I m using
for ( i = 0 ; i < n ; i++ )
{
for ( c = 0 ; c <= pow(2,i) ; c=c++ )
I would really appreciate any suggestions
Compute the number of iterations of the inner loop once and reuse it instead of computing it everytime.
Don't use pow(2, i). Use the more reliable 1 << i.
Don't use c = c++. Just use c++. I am not sure c = c++ is guaranteed to be c = c+1.
for ( i = 0 ; i < n ; i++ )
{
int nextCount = (1 << i);
for ( c = 0 ; c <= nextCount ; c++ )
You can use the fact that to compute a small power of two in C++ you can use a bit shift left:
for ( i = 0 ; i < n ; i++ ) {
for ( c = 0 ; c < (1 << i) ; c++ ) {
...
}
}
The reason behind this "magic" is the same as the reason why adding a zero to the right of a decimal number multiplies the number by ten.
Note that since you start the iteration of the inner loop at zero, you need to use <, not <=. Otherwise you would iterate 2n+1 times.
You'll want to use something like everyone else has suggested:
for (int i=0 ; i<n ; i++){
for(int c=0 ; c < (1<<i) ; c++){
//do computations
}
}
The reason you want to use < instead of <= is becase <= will actually give you (2^i)+1 iterations, due to counting zero.
The reason you want to want to use the bitshift operation 1<<i, is because integers are already in base two, and adding zeros on the end is the equivelant of multiplying by two repeatedly. (1 is automatically created as an integer, while 1.0 is automatically created as a float. You could not safely do this with floats: 1.0<<1 bitshifts to 1.70141e+38, if you can get the compiler to do it.)
Finally, you want to use c++ because c++ increments c, but returns the original value, so your inner for-loop always keeps the original value and never increments.
Related
I am looking at the following: Operations Counting Example
Which is supposed to present the operations count of the following pseudocode:
Algorithm prefixAverages(A)
Input array A of n numbers
Output array B of n numbers such that B[i] is the average
of elements A[0], A[1], … , A[i]
for i = 0 to n - 1 do
b = 0
for j = 0 to i do
b = b + A[j]
j++;
B[i] = b / (i + 1)
return B
But I don't see how the counts on the inner for loop are reached. It says that for case i=0; j=0; the inner for loop runs twice? But it strikes me that it should only run once to see that 0 < 0. Can anyone provide insight into where the given operations count comes from or provide their own operations count?
This is under the assumption that primitive operations are:
Assignment
Array access
Mathematical operators (+, -, /, *)
Comparison
Increment/Decrement (math in disguise)
Return statements
Let me know if anything is unclear or you need more information
When the article you are following says "for var <- 0 to var2", it is like "for (var = 0; var <= var2; var++), so yes, when i = 0, it enters the "for" twice (once when i = 0, and again when i = 1, then it goes out).
(Sorry if bad english)
Edit and improve: When I calculate the complexity of a program, the only thing that interest me is the big O complexity; in this case, you have that the 'i' loop run 'n' times, and the 'j' loop run 'i' times, so the 'i' loop runs (1+2+3+...+n) times, that is n(n+1)/2 times, and that is an O(n**2) complexity.
In the first line, you have an assignament (i = something), and a comparison (i <= n-1) ("2 operations") for each i value, and as the last value is i=n, it does those 2 operations since i=0, until i=n, and as those are n+1 values (from 0 to n), this line do 2(n+1) operations.
The second line is a little obvious, as it enters the loop n times (since i=0, until i=n-1).
On the second loop, it do 2 things, an assignament, and a comparison (just as the first loop), and it do this i+2 times (for example, when i=0, it enters the loop 1 time, but it has to do the i=1 assignament, and the 1<=0 comparison, so its 2 times in total), so it do this calculus 2(i+2) times, but it do this since i=0, until i=n-1, so to calculate all of this, we have to do the sum (sum from i=0 until i=n-1: 2(i+2)) = 2((sum of i from 0 to n-1) + (sum of 2 from i=0 to i=n-1)) = 2((n(n-1)/2) + 2n) = n(n-1) + 4n = n"2 - n + 4n = n"2 + 3n.
I'll continue this later, I hope my answer so far is helpful for you. (again, sorry if some bad english)
How can I generate k unique random numbers in the interval [0,n-1]?
I used the following code:
for( int i = 0 ; i < n ; ++i ){
a[i]=i;
}
std::random_shuffle( a, a+n ) ;
for(int i=0;i<k;++i){
ra[i]=a[i];
}
which takes first k elements.
Can anyone refer me to a faster approach?
std::random_shuffle:
http://www.cplusplus.com/reference/algorithm/random_shuffle/
For small values of n your method is well suited. Of course, you can mix elements of the array manually, but this is unlikely to be much faster.
For large values you can use the Linear Congruential Generator:
r[n + 1] = (a * r[n] + c) % m;
Where m (modulus) is equal to your n.
To maximize the length of generated sequence you should to follow some rules when choosing values a and c (see link above for details).
Of course, k should me smaller than n.
Wikipedia claims that the failure function table can be computed in O(n) time.
Let's look at its `canonical' implementation (in C++):
vector<int> prefix_function (string s) {
int n = (int) s.length();
vector<int> pi (n);
for (int i=1; i<n; ++i) {
int j = pi[i-1];
while (j > 0 && s[i] != s[j])
j = pi[j-1];
if (s[i] == s[j]) ++j;
pi[i] = j;
}
return pi;
}
Why does it work in O(n) time, even if there is an inner while-loop? I'm not really strong at the analysis of algorithms, so may somebody explain it?
This line: if (s[i] == s[j]) ++j; is executed at most O(n) times.
It caused increase in the value of p[i]. Note that p[i] starts at same value as p[i-1].
Now this line: j = pi[j-1]; causes decrease of p[i] by at least one. And since it was increased at most O(n) times (we count also increases and decreases on previous values), it cannot be decreased more than O(n) times.
So it as also executed at most O(n) times.
Thus the whole time complexity is O(n).
There's already two answers here that are correct, but I often think a fully laid out
proof can make things clearer. You said you wanted an answer for a 9-year-old, but
I don't think it's feasible (I think it's easy to be fooled into thinking it's true
without actually having any intuition for why it's true). Maybe working through this answer will help.
First off, the outer loop runs n times clearly because i is not modified
within the loop. The only code within the loop that could run more than once is
the block
while (j > 0 && s[i] != s[j])
{
j = pi[j-1]
}
So how many times can that run? Well notice that every time that condition is
satisfied we decrease the value of j which, at this point, is at most
pi[i-1]. If it hits 0 then the while loop is done. To see why this is important,
we first prove a lemma (you're a very smart 9-year-old):
pi[i] <= i
This is done by induction. pi[0] <= 0 since it's set once in the initialization of pi and never touched again. Then inductively we let 0 < k < n and assume
the claim holds for 0 <= a < k. Consider the value of p[k]. It's set
precisely once in the line pi[i] = j. Well how big can j be? It's initialized
to pi[k-1] <= k-1 by induction. In the while block it then may be updated to pi[j-1] <= j-1 < pi[k-1]. By another mini-induction you can see that j will never increase past pi[k-1]. Hence after the
while loop we still have j <= k-1. Finally it might be incremented once so we have
j <= k and so pi[k] = j <= k (which is what we needed to prove to finish our induction).
Now returning back to the original point, we ask "how many times can we decrease the value of
j"? Well with our lemma we can now see that every iteration of the while loop will
monotonically decrease the value of j. In particular we have:
pi[j-1] <= j-1 < j
So how many times can this run? At most pi[i-1] times. The astute reader might think
"you've proven nothing! We have pi[i-1] <= i-1 but it's inside the while loop so
it's still O(n^2)!". The slightly more astute reader notices this extra fact:
However many times we run j = pi[j-1] we then decrease the value of pi[i] which shortens the next iteration of the loop!
For example, let's say j = pi[i-1] = 10. But after ~6 iterations of the while loop we have
j = 3 and let's say it gets incremented by 1 in the s[i] == s[j] line so j = 4 = pi[i].
Well then at the next iteration of the outer loop we start with j = 4... so we can only execute the while at most 4 times.
The final piece of the puzzle is that ++j runs at most once per loop. So it's not like we can have
something like this in our pi vector:
0 1 2 3 4 5 1 6 1 7 1 8 1 9 1
^ ^ ^ ^ ^
Those spots might mean multiple iterations of the while loop if this
could happen
To make this actually formal you might establish the invariants described above and then use induction
to show that the total number of times that while loop is run, summed with pi[i] is at most i.
From that, it follows that the total number of times the while loop is run is O(n) which means that the entire outer loop has complexity:
O(n) // from the rest of the outer loop excluding the while loop
+ O(n) // from the while loop
=> O(n)
Let's start with the fact the outer loop executes n times, where n is the length of the pattern we seek. The inner loop decreases the value of j by at least 1, since pi[j] < j. The loop terminates at the latest when j == -1, therefore it can decrease the value of j at most as often as it has been increased previously by j++ (the outer loop). Since j++ is executed in the outer loop exactly n times, the overall number of executions of the inner while loop is limited to n. The preprocessing algorithm therefore requires O(n) steps.
If you care, consider this simpler implementation of the preprocessing stage:
/* ff stands for 'failure function': */
void kmp_table(const char *needle, int *ff, size_t nff)
{
int pos = 2, cnd = 0;
if (nff > 1){
ff[0] = -1;
ff[1] = 0;
} else {
ff[0] = -1;
}
while (pos < nff) {
if (needle[pos - 1] == needle[cnd]) {
ff[pos++] = ++cnd;
} else if (cnd > 0) {
cnd = ff[cnd]; /* This is O(1) for the reasons above. */
} else {
ff[pos++] = 0;
}
}
}
from which it is painfully obvious the failure function is O(n), where n is the length of the pattern sought.
I have two lists of times in nanoseconds. Each list can have 10^12 elements or more. My current implementation is to take a subset of both lists, compare the times in that subset using for loops and output correlated times, then take another subset. For each subset comparison this runs in approx. (m*n) where m is the size of list 1 subset and n is the size of the list 2 subset, which is obviously a bad algorithm.
I also have a clock that is smaller than the total time of my data sets, so there are rollovers in the data to be concerned with at certain times.
List 1 has certain events, and list two has secondary events. I want to know if the secondary events happen within a certain time from the primary events. There is also a lot of noise, so I need to create a histogram of correlated times and look for a time where there is a statistically significant signal.
I would like to know if there is a known efficient algorithm that can be used in C++ from any open source library, or an efficient algorithm that I can implement, to search the times of both lists, and output the items that fall within the window.
Here is an example of the brute force function:
int correlate_lists( int window )
{
for( int i = 0 ; i < list1.size() ; i++ )
{
for( int j = 0 ; j < list2.size() ; j++ )
{
if( list2[j].time() > list1[i].time() && (list2[j].time() - list1[j].time()) < window )
{
printf("Time: %d\n, list2[j].time() - list[1].time() );
}
}
}
}
If your two lists are sorted by time, you can walk through the lists efficiently:
for( int i = 0, j = 0 ; i < list1.size() ; ++i )
{
while( j < list2.size() && list2[j].time() <= list1[i].time() )
{
++j;
}
int k = j;
while( k < list2.size() && list2[k].time() < list1[i].time() + window)
{
printf("Time: %d\n, list2[k].time() - list1[i].time() );
++k;
}
}
If the lists are sorted, surely you can use a binary search to find the "window" position?
Problem
Given a 2D 0/1 Matrix, Find the row(s) with maximum number of 0s.
Example
11111000
11111110
11100000
11000000
11110000
Output
11000000
My idea
If each 0s row is continuous, we can scan from two ends for each row. Common sense says to scan with O(n^2).
Are there any O(n) solutions?
if every row is like 1....10...0, you could binary search first zero in each row.
That would be O(n*lg(n))
for an arbitrary matrix, you must check every cell, so it must be O(n^2).
You can do it in O(N) as follows:
Start at A[i][j] with i=0 and j=No_of_columns-1.
0, keep moving to the left by doing j--
A[i][j] =
1, move down to the next row by doing i++
When you reach the last row or the last column, the value of j will be the answer.
Pseudo code:
Let R be number of rows
Let C be number of columns
Let i = 0
Let j = C-1
Let max1Row = 0
while ( i<R && j>=0 )
if ( matrix[i][j] == 0 )
j--
max1Row = i
else
i++
end-while
print "Max 0's = j"
print "Row number with max 0's = max1Row"
As #amit says:
scanning a matrix is considered O(n). The standard big O notation stands for relationship between run time and the input size. Since your input is of size #rows*#cols, you should regard this number as n, and not to #rows.
Therefore, this is as O(n) as you can get. :)
std::vector<std::string> matrix;
std::vector<std::string>::iterator max = matrix.begin();
for(std::vector<std::string>::iterator i = matrix.begin(); i != matrix.end(); ++i)
{
if(count_zeros(*i) > count_zeros(*max))
max = i;
}
count_zeros() should look something like this:
size_t count_zeros(std::string s)
{
size_t count = 0;
for(std::string::iterator i = s.begin(); i != s.end(); ++i)
if(*i == '0')
++count;
return i;
}
If all the 0s in each row are guaranteed to be at the rightmost, you can do it in O(sqrt(n)).
Put cursor on (len, 0)
If the value to the left of the cursor is 0, move the cursor left. Else, move it down.
If bottom row is reached, terminate. Else, go to step 2.
std::vector<std::string> matrix;
std::vector<std::string>::iterator y = matrix.begin();
for(std::string::reverse_iterator x = (*y).rbegin(); x < matrix.rend(); )
{
if(*x != '0')
{
x -= (*y).rbegin();
++(*y);
x += (*y).rbegin();
continue;
}
++x;
}
With the give sample set (were all starts with 111 and ends in 000 with no mix of 1 and 0) the set can simply be searched in a single pass with a test of A&(A xor B) for testing if there are more or less zero than the previous row -- that is a loop of O(n)....
Here a quick solution with just one if or each row (not for each element):
As your matrix just holds zeros and ones, add up the elements of each row and then return the index/indices of the minimum/minimae.
P.S.: adding ones is really fast when using assmbly inc or ++Variable in C++
Edit: Here another idea. If you really just need 0/1 matrices that do not excedd say 64 columns, you could implement them as bit matrices using ordinary unsigned 64 integers. By setting and deleting the respective bit you can define the entry (0 or 1). The effect: an o(n) check (let me know if I am wrong) as followsm, where intXX is rowXX. The first idea is to extract different bits via XOR
SET tmpA to int01
FOR I = 1 to n-1
XOR intI with intI+1, store result in tmpX
AND tmpX with intI, store result in tmpM
AND tmpX with intI+1, store result in tmpN
if (tmpN < tmpM)
SET tmpA to intI+1
ENDFOR
tmpA should now hold the (last) row with fewest zeros.
Cheers,
G.