1)
i = 0;
while(i < N){
j = i+1;
while(j < N && p[i].first == p[j].first && p[j].second - p[i].second < K) j++;
i = j; res++;
}
2)
for(i=0;i<N;i++){
j = i+1;
while(j < N && p[i].first == p[j].first && p[j].second - p[i].second < K) j++;
i = j; res++;
}
the first code and the second code differs only due to while loop in 1) and for loop in
2). But According to me the outputs due to both of them should be same but it differs.
Both the above codes are only a part of the total code. But I should tell you the output due to 1) is 2 whereas due to 2) is 3.
I don't why the answer is different because everything happening is same.
The for loop increments i twice. Once in the for loop definition itself (i++) and then indirectly via j.
The while loop only does the indirect increment via j. So the two examples are not the same.
I think to make equals the loops you should omit the increment in for:
for(i=0; i<N; ){
In your for loop, the variable i is incremented twice in your code:
First time at
for(i=0;i<N;i++){
and second time at
j = i+1 followed by i = j
Related
is this loop statement is correct?
if not correct then what alternative way?
I am trying to o(n) loop statement like this-
for(int i=0 ; i<n ; i++ , j=n ; j<n*2 ; j++){
continue;
}
The construct is wrong, you cannot you two loops in one construct, but you can have more than one variable controlling the iteration.
For example, you can have
Two (or more) variables, i and j, initialized with certain values.
A loop controlling statement, involving operation and condition check on i and j (and others, if defined).
Finally, you can control the increment or decrement of i and j (and others, if defined).
A sample construct can be:
for (int i = 0, j = n; i < n && j < n * 2; ++i, ++j)
|^^^^^^^| -------- variable modification
| | |^^^^^^^^^^^^^^^^^| ---------------- loop condition
|^^^^^^^^^^^^^^^|--------------------------------------- initialization
What you seem to want is something like:
for (int i = 0, j = n; i < n && j < n * 2; ++i, ++j)
{
continue;
}
To help you better understand what I did and why, and how you can do such transformations in the future, you need to understand how a for loop is really handled by the compiler: As a special while loop.
For example, if you have
for (a; b; c)
{
d;
}
then that's equivalent to this:
{
a;
while (b)
{
d;
c;
}
}
If we take what you (probably) want, in the form of a while loop then it would be
{
int i = 0, j = n; // a in my example above
while (i < n && j < n * 2) // b in my example above
{
continue; // d in my example above
++i, ++j; // c in my example above
}
}
Now it's easy to translate it to the for loop I showed initially.
As noted in a comment, the while loop shown here is a little misleading, as it won't actually do the increment. But then I assume your real loop doesn't have an unconditional continue statement as the only statement in the body. That would make the loop rather meaningless. However the principle is still valid, even if the example isn't.
for(int i=0 ; i<n ; i++ , j=n ; j<n*2 ; j++){
continue;
}
The above code is wrong
but it can be written as
for(int i = 0 ,j = n; i < n ,j < n * 2; i++ ,j++)
The above code is correct
i=0 and j=n is initialization
i<n and j<n*2 is loop condition
i++ and j++ is incrementation
I have 3 nested loops in which the code doesn't in anyway modify the counters, I need the value of the topmost-level loop counter to use later in the code. It looks like this
int i;
for( i = 0; !found && i <f_i.size();i++){
for(unsigned int j = 0; !found && j < f_g.size();j++){
for(unsigned int k = 0; !found && k < f_g.size();k++){
///Do Stuff
found = (/*Condition that's fulfilled after 2 iterations on k*/);
}
}
}
//Stuff that uses i
The condition is fulfilled after 2 iteration of the innermost loop, so i has the value 0 at that point.
Using GDB I saw that the value of i jumps to 1 after the condition is checked in the topmost loop, which gives me a wrong later in my program, or worse an out of bounds access.
Thanks in advance
This is how for loops work. The increment is done before the condition is checked.
The proper way (easier to read, easier to maintain) to do what you want is to add a variable, outside the loop.
int index;
And set it when you find the element:
found = ...
if (found) index = i;
The variable i is incremented due to the third expression of the for loop
int i;
for( i = 0; !found && i <f_i.size();i++){
^^^^
for(unsigned int j = 0; !found && j < f_g.size();j++){
for(unsigned int k = 0; !found && k < f_g.size();k++){
///Do Stuff
found = (/*Condition that's fulfilled after 2 iterations on k*/);
}
}
}
To avoid this you can write for example
int i;
for( i = 0; !found && i <f_i.size();){
for(unsigned int j = 0; !found && j < f_g.size();j++){
for(unsigned int k = 0; !found && k < f_g.size();k++){
///Do Stuff
found = (/*Condition that's fulfilled after 2 iterations on k*/);
}
}
i += !found;
}
Or instead of the expression statement
i += !found;
you can use the if statement like
if ( !found ) ++i;
Also the code will look more readable if the variable i will be initialized before the loops for example like
int i = 0;
while ( !found && i < f_i.size() ){
for(unsigned int j = 0; !found && j < f_g.size();j++){
for(unsigned int k = 0; !found && k < f_g.size();k++){
///Do Stuff
found = (/*Condition that's fulfilled after 2 iterations on k*/);
}
}
i += !found;
}
As others have said (or, at least, implied): once the (outermost) for loop is entered†, the variable, i, will be incremented at the end of that loop, before the condition is tested, to see if another loop should be run ...
... that is, unless you 'jump out' of the loop using a break statement!
So, the following, slightly modified, code will not increment i (at all) if found becomes true during the first iteration of the outermost loop:
int i;
for (i = 0; !found && i < f_i.size(); i++) {
for (unsigned int j = 0; !found && j < f_g.size(); j++) {
for (unsigned int k = 0; !found && k < f_g.size(); k++) {
///Do Stuff
found = (/*Condition that's fulfilled after 2 iterations on k*/);
}
}
// If "found" becomes true, exit the loop immediately, AVOIDING THE INCREMENT:
if (found) break;
}
So, while the other answers are very good, and the code solutions they offer are perfectly valid, the proposal here is a far more 'minimal' adjustment to your code. I hope it helps.
Note: You could, of course, add similar break statements to the inner loops; however, as your j and k variables are declared locally to those loops, it would appear that undesired increments to their values is not relevant. Furthermore, break cannot be used to jump out of multiple, nested loops.
†Also, be aware that if the found variable is true before the outermost for loop is encountered, that loop will not be executed (obviously) and, thus, the i variable will not be incremented in that case.
Say I have a for loop as:
for(int i=0,j=i+1;i<n-1,j<n;j++)
{
//some code
if(condition)
{
i++;
j=i;
}
}
What will be the time complexity and why?
Edited:
void printAllAPTriplets(int arr[], int n)
{
for (int i = 1; i < n - 1; i++)
{
// Search other two elements of
// AP with arr[i] as middle.
for (int j = i - 1, k = i + 1; j >= 0 && k < n;)
{
// if a triplet is found
if (arr[j] + arr[k] == 2 * arr[i])
{
cout << arr[j] << " " << arr[i]
<< " " << arr[k] << endl;
// Since elements are distinct,
// arr[k] and arr[j] cannot form
// any more triplets with arr[i]
k++;
j--;
}
// If middle element is more move to
// higher side, else move lower side.
else if (arr[j] + arr[k] < 2 * arr[i])
k++;
else
j--;
}
}
}
What would be the time complexity of this particular function and why?? #walnut #DeducibleSteak #Acorn .This is the code for "Printing all triplets in sorted array that form AP"
O(n^2) is when you iterate through all the possible values of one variable each time you iterate through the second one. As such:
for(int i=0; i < n; i++){
for (int j = 0; j < m; j++{
//Do some action
}
}
In your example, even though you're using two vars, but it's still a O(n).
Assuming that increasing i by one takes one second, then assigning the new i to j takes one second too, then the complexity is O(2n). Since constant numbers are insignificant when speaking about complexities, then the complexity of your code is still O(n)
The loop you have written does not make sense, because you are using the comma operator and discarding one of the conditions, so it is equivalent to j < n.
Even if the condition gets triggered many times (but a constant number w.r.t. n, i.e. not becoming larger as n grows), then you can easily show you will do <= k*n iterations, which means O(n) iterations.
If that is not true, but the condition is at least side-effect free, then you can only bound it by O(n^2), e.g. as #walnut suggests with j == n - 1 (like in a triangle matrix).
If you allow for side-effects in the condition (e.g. j = 0, with an equals sign), then it can be an infinite loop, so there is no possible bound.
I have an array a={1,2,3,3,2,2,3,3} and I need to remove the duplicates like this:
1: a={1,2,2,2,3,3}
2: a={1,2,3,3}
3: a={1,2}
I need to remove 2 consecutive duplicates: (1,2,3,3 will be 1,2), (1,2,2,2 will be 1,2).
Here is my try, but as you can see, I need some help.
#include <iostream>
int main()
{
int n;
std::cin >> n;
int a[n];
for (int i = 0; i < n; i++)
std::cin >> a[i];
int i, j;
for (i = 0; i < n; i++)
if (a[i] == a[i + 1]) {
for (j = i + 1; j < n; j++)
a[j - 1] = a[j];
n--;
i--;
}
if (n != 0)
for (int i = 0; i < n; i++)
std::cout << a[i] << " ";
return 0;
}
My problem is that I don't know how to remove 2 consecutive values. After multiple tries, I can't resolve this. Thank you in advance!
I'm not going to write code for you, but here are my thoughts.
First, write a function to check if there even exists "consecutive duplicates":
//returns true if there are no consecutive duplicates within the array, false otherwise
func noConsecDups(arr a)
for int i = 0, i <= a.length-2, i++
if a[i] = a[i++]
return false
end of if
end of loop
return true
end function
Now, write a function that removes the consecutive duplicates recursively (might not have to do it recursively, that's just my initial thought) while checking to see if you even need to remove any!
//function that takes an array as input and returns the array with all consecutive duplicates removed
func removeConsecDups(arr a)
if a.length is 1, return a
if a.length is 2 and a[0] != a[1], return a
if(noConsecDups(a)) then there are no consecutive duplicates, return a
otherwise look through the array and just remove the first consecutive duplicates
for int j = 0, j <= a.length-2, j++
if a[j] = a[j+1]
remove a[j+1]
remove a[j]
break
end if statement
end loop
recursively call removeConsecDups(a)
end function
If you just need the final result (an array with no consecutive duplicates left) then your best bet is probably to use a stack and just traverse the whole input array once, comparing the values to the stack top and poping the duplicates off the stack.
If you need to print out the array state after every intermediate step, then #BarronDuBois's suggestion is the way to go.
Either way the code itself should be simple enough, I'd be glad to help with any specific issue.
I have been working on an assignment question for days and cannot seem to get the correct output (I've tried so many things!) The question is:
Write a program that uses two nested for loops and the modulus operator (%) to detect and print the prime numbers from 1 to 10,000.
I have been doing from 1 to 10 as a small test to ensure its working. I am getting 2,3,5,7,9 as my output, so I know something is wrong. When I increase the number from 10 to 20 it is printing 2 plus all odd numbers. I am including my code below. Thanks!!
int main() {
for (int i=2; i <=10; i++){
for (int j=2; j<=i; j++){
if (i%j==0 && j!=i) {
break;
}
else {
cout<< i <<endl;
break;
}
}
}
}
In addition to Sumit Jindal's answer inner for loop can be done by this way as well:
for(int j=2; j*j<=i ; j++)
If we think about every (x,y) ordered pair that satisfies x*y = i, maximum value of x can be square root of i.
The problem lies in the if-else branch. Your inner loop will be run exactly once because it will break out of the inner loop as a result of your if else branch.
When you first enter the inner loop the value of j is 2. Your condition will test if variable i is divisible by 2. If it is it breaks. Other wise (your else branch) will print the value of i and breaks out.
Hence printing odd numbers.
Break out of the inner loop and check whether j equals i in outer loop. You have to make j available for outer loop.
Your print statement is within the inner loop, and it should not be - it's only a prime if you run all the way through the inner loop without finding a divisor.
As a second point, you only need to check for divisors up to the square root of i, not all the way up to i.
You are breaking the inner loop after the first iteration itself, which is checking if the number(ie i) is different from j and is divisible by 2 or not (since j=2 for the first iteration)
I am getting 2,3,5,7,9 as my output
This is because every odd number fails the if and is printed in else condition
A minor correction in your code, adding a flag. Also you don't need to run the inner loop i times, infact only i/2 times is sufficient. This is simple mathematics, but will save significant number of CPU cycles (~5000 iterations lesser in your case)
#include <iostream>
int main()
{
int n = 10;
for(int i=2; i<=n; i++){
bool isPrime = true;
for(int j=2; j<=i/2; j++){
if(i!=j && i%j==0){
isPrime = false;
break;
}
}
if(isPrime)
std::cout << i << " ";
}
return 0;
}
Another version, if you don't mind output in reverse order.
int n = 10;
for (int i = n; i > 1; --i)
{
int factorCount = 0;
for (int j = 2; j <= n; ++j)
{
if (i % j == 0)
factorCount++;
if (factorCount > 1)
break;
}
if (factorCount == 1)
cout << i << endl;
}
int main() {
for (int i = 2; i <= 100; i++) {
for (int j = 2; j < i; j++) {
if (i%j == 0)
break;
if (j==i-1) // means has never run previous if blog
cout << i << endl;
}
}
return 0;
}