complexity of for Loop having same variable name - algorithm

I was trying this below code to find the time complexity and somewhere Lecturer said that here you have same variable name so time complexity would be O(n^3) , I think it should be O(n^6) can someone help me Iam confused
int i ;
for(i=1;i<=n;++i)
{
for(i=1;i<=n^2;++i)
{
for(i=1;i<=n^3;++i)
{
x=y+z;
}
}
}

The first for loop starts, then the second and the third.
The third for loop runs until i>n³.
Once this happens, the second for loop will finish one iteration, it then tries to check if i<=n², but since i > n³, it ends the loop.
This happens for the first loop as well.
This happens mainly because the i variable is block scoped and since all three loops are nested, they all share the same variable.

Related

Can someone explain me this code intuitively?

I understand recursion and what the advantages it brings to writing code efficiently. While I can code recursive functions, I cannot seem to wrap my head around how they work. I would like someone to explain me recursion instinctively.
For example, this code:
int fact(int n)
{ if n<0:
return -1
elif n==0:
return 1
else
return n*fact(n-1)
}
These are some of my questions:
Let's say n=5. On entering the function,the control goes to the last return statement since none of the previous conditions are satisfied.
Now, roughly, the computer 'writes' something like this: 5*(fact(4))
Again, the fact() function is called and the same process gets repeated except now we have n=4.
So, how exactly does the compiler multiply 5*4 and so on until 2 since its not exactly 5*4 but 5*fact(4). How does it 'remember' that it has to multiply two integers and where does it store the temporary value since we haven't provided any explicit data structure?
Again let's say n=5. The same process goes on and eventually n gets decremented to 0. My question is why/how doesn't the function simply return 1 as stated in the return statement. Similar to my previous question, how does the compiler 'remember' that it also has 180 stored for displaying?
I'd be really thankful if someone explains this to me completely so that can understand recursion better and intuitively.
Yeah, for beginners recursion can be quite confusing. But, you are already on the right track with your explanation under "1.".
The function will be called recursively until a break condition is satisfied. In this case, the break condition is satisfied when n equals 0. At this point, no recursive calls will be made anymore. The result of each recursive call is returned to the caller. The callers always "wait" until they get a result. That's how the algorithm "knows" the receiver of the results. The flow of this procedure is handled by the so called stack.
Hence, in your informal notation (in this example n equals 3):
3*(fact(2)) = 3*(2*fact(1)) = 3*(2*(1*fact(0))).
Now, n equals 0. The inner fact(0) therefore returns 1:
3*(2*(1*(1)))) = 3*(2*(1)) = 3*(2) = 6
You can see a bit like this
The function fact(int n) is like a class and every time you call fact(int n) you create an instance of that class. By creating them (calling them) from the same function, you are creating a chain of instances. Once you reach break condition, those functions start returning one by one and the value they returned to calculate a new value in the return statement return n*fact(n-1) e.g. return 3*fact(2);

Should I expect to see the counter in `for` loop changed inside its body? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I'm reading someone else's code and they separately increment their for loop counter inside the loop, as well as including the usual afterthought. For example:
for( int y = 4; y < 12; y++ ) {
// blah
if( var < othervar ) {
y++;
}
// blah
}
Based on the majority of code others have written and read, should I be expecting to see this?
The practice of manipulating the loop counter within a for loop is not exactly widespread. It would surprise many of the people reading that code. And surprising your readers is rarely a good idea.
The additional manipulation of your loop counter adds a ton of complexity to your code because you have to keep in mind what it means and how it affects the overall behavior of the loop. As Arkady mentioned, it makes your code much harder to maintain.
To put it simply, avoid this pattern. When you follow "clean code" principles, especially the single layer of abstraction (SLA) principle, there is no such thing as
for(something)
if (somethingElse)
y++
Following the principle requires you to move that if block into its own method, making it awkward to manipulate some outer counter within that method.
But beyond that, there might be situations where "something" like your example makes; but for those cases - why not use a while loop then?
In other words: the thing that makes your example complicated and confusing is the fact that two different parts of the code change your loop counter. So another approach could look like:
while (y < whatever) {
...
y = determineY(y, who, knows);
}
That new method could then be the central place to figure how to update the loop variable.
I beg to differ with the acclaimed answer above. There is nothing wrong with manipulating loop control variable inside the loop body. For example, here is the classical example of cleaning up the map:
for (auto it = map.begin(), e = map.end(); it != e; ) {
if (it->second == 10)
it = map.erase(it);
else
++it;
}
Since I have been rightfully pointed out to the fact that iterators are not the same as numeric control variable, let's consider an example of parsing the string. Let's assume the string consists of a series of characters, where characters prefixed with '\' are considered to be special and need to be skipped:
for (size_t i = 0; i < s_len; ++i) {
if (s[i] == '\\') {
++i;
continue;
}
process_symbol(s[i]);
}
Use a while loop instead.
While you can do this with a for loop, you should not. Remember that a program is like any other piece of communication, and must be done with your audience in mind. For a program, the audience includes the compiler and the next person to do maintenance on the code (likely you in about 6 months).
To the compiler, the code is taken very literally -- set up a index variable, run the loop body, execute the increment, then check the condition to see if you are looping again. The compiler doesn't care if you monkey with the loop index.
To a person however, a for loop has a specific implied meaning: Run this loop a fixed number of times. If you monkey with the loop index, then this violates the implication. It's dishonest in a sense, and it matters because the next person to read the code will either have to spend extra effort to understand the loop, or will fail to do so and will therefore fail to understand.
If you want to monkey with the loop index, use a while loop. Especially in C/C++/related languages, a for loop is exactly as powerful as a while loop, so you never lose any power or expressiveness. Any for loop can be converted to a while loop and vice versa. However, the next person who reads it won't depend on the implication that you don't monkey with the loop index. Making it a while loop instead of a for loop is a warning that this kind of loop may be more complicated, and in your case, it is in fact more complicated.
If you increment inside the loop, make sure to comment it. A canonical example (based on a Scott Meyers Effective C++ item) is given in the Q&A How to remove from a map while iterating it? (verbatim code copy)
for (auto it = m.cbegin(); it != m.cend() /* not hoisted */; /* no increment */)
{
if (must_delete)
{
m.erase(it++); // or "it = m.erase(it)" since C++11
}
else
{
++it;
}
}
Here, both the non-constant nature of the end() iterator and the increment inside the loop are surprising, so they need to be documented. Note: the loop hoisting here is after all possible so probably should be done for code clarity.
For what it's worth, here is what the C++ Core Guidelines has to say on the subject:
http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-loop-counter
ES.86: Avoid modifying loop control variables inside the body of raw
for-loops
Reason The loop control up front should enable correct
reasoning about what is happening inside the loop. Modifying loop
counters in both the iteration-expression and inside the body of the
loop is a perennial source of surprises and bugs.
Also note that in the other answers here that discuss the case with std::map, the increment of the control variable is still only done once per iteration, where in your example, it can be done more than once per iteration.
So after the some confusion, i.e. close, reopen, question body update, title update, I think the question is finally clear. And also no longer opinion based.
As I understand it the question is:
When I look at code written by others, should I be expecting to see "loop condition variable" being changed in the loop body ?
The answer to this is a clear:
yes
When you work with others code - regardless of whether you do a review, fix a bug, add a new feature - you shall expect the worst.
Everything that are valid within the language is to be expected.
Don't make any assumptions about the code being in acordance with any good practice.
It's really better to write as a while loop
y = 4;
while(y < 12)
{
/* body */
if(condition)
y++;
y++;
}
You can sometimes separate out the loop logic from the body
while(y < 12)
{
/* body */
y += condition ? 2 : 1;
}
I would allow the for() method if and only if you rarely "skip" an item,
like escapes in a quoted string.

Compare 43 variables in all possible ways

I am trying to figure out which method is the best way to cross compare 43 variables (data sets, data)
I need to compare variable 1 with variable 2,3,4,5,6,7....43 and then compare variable 2 with variable 1,3,4,5,6,7....43 and so on, to variable no. 43.
I think i should use some kind of a loop, but i am clueless how to perform this operation efficient.
I think I just need some kind of pseudo code. Either way I want to do this in a do-file in Stata.
Assuming e.g. variables var1-var43 and that the "comparison" between the first and the second differs from that between the second and the first, which is what your question implies, then
forval i = 1/43 {
forval j = 1/43 {
if `i' != `j' {
<code for comparison between var`i' and var`j'>
}
}
}
With other variable names, foreach might be better.
As #NickCox suggested, you could use a O(NxN) nested loop. If that takes too long, which it could if your "43" is actually 1000, then there's a better way. Sort each list (indirectly), which is O(N logN), and run a merge-order loop, which is O(N), so altogether it is O(N logN).

How does the pascal for loop work?

I've got a question related to the way the for loop works in Pascal:
Program example;
var i:integer;
Begin
i:=7;
for i:=1 to i do write(i);
End.
This piece of code outputs: 1234567.
I think that the compiler makes a secondary copy of the variable i, and then uses that one in the for loop.
Note that this is REQUIRED to work in Pascal according to the ISO7185 standard. The "end value" should be copied before the loop counter is modified.
https://github.com/Leporacanthicus/lacsap/blob/master/test/Basic/iso7185pat.pas#L761
In the for loop in Pascal we have variable called loop counter which controls the iterations of the loop, and this variable changes in each iteration of the loop, so it's that i which is declared here: i:=1 in your code.
The second is the variable declared above the loop which is called also i but it's a variable which is the final value for the loop.
Consider this:
Program example;
var i:integer;
var addr:^word;
Begin
i:=10;
for i:=1 to i do addr:=#i;
addr^ := addr^+1; { I add 1 to the last loop counter }
writeln(i); { This is final variable, I don't add anything to the final variable of the loop }
writeln(addr^); { This is value of the last loop counter index }
{ Both variables give us the same result }
{ Proposal: In my opinion, your guess about the copy is correct }
End.
As in comment in the code - in my opinion, pascal creates a copy of this variable.
Hope it will help!
If yes please let me know by voting up.
Regards!
The point here is the Pascal compiler will set the parameters for the for once, at the first execution. Then it sets a start point i:=1 and and end point 7 before doing anything with the control value, then starts the loop.
But I should point that this is bad practice in programming. Unless you are just making an academical or speculative question, I see no reason to "save" a variable name doing something like this.
It is interesting to notice too that this abuse of the control variable name may cause unpredictable results if this is done inside the loop.
As they use to say in those programs who show dangerous adventures, don't try to do this at home!

Readability: list iteration with get_first/get_next, "while" vs. "for" loop

Let's say you would like to iterate trough a list using an initial get_first() with subsequent calls to get_next() which returns NULL at the end of the list.
Which one would you prefer reading?
element = get_first(list);
while (element)
{
process(element);
element = get_next(list);
}
vs.
for (element = get_first(list); element; element = get_next(list))
{
process(element);
}
The state of an iteration is saved inside the list struct.
I am personally more used to the while version but when I saw someone use the for version I also easily understood what was going on so now I wonder which one is easier to read for most people.
Both are very readable. You won't confuse your readers with either. The while loop is arguably a bit more readable (But people mileage may vary...) so I would probably use it if the list was only iterated over once and use the more concise for loop otherwise.

Resources