For Loop Constructs - c#

Will this loop execute exactly N Times?
for (int i = 0; i < N; i++)
{
//statement
someMethodCall();
}
Will this loop execute at most N Times?
for (int i = 1; i < N; i++)
{
someMethodCall();
}
Will this loop execute at least N Times?
for (int i = 0; i <= N; i++)
{
//statement
someMethodCall();
}
What should I do if I need to execute the statement between m and n times, e.g. calling a method?

The answers to your three questions are yes, no, and yes, I suppose, although that third answer is a bit deceptive; it'll execute N times, no more and no less (unless there's an exception which terminates the loop abnormally.) You can write a for loop to loop a definite number of times, or until some condition becomes true, and then you have the ability to use break or return to terminate the loop early.
But there's no notion of executing "at least N times;" it's simply not part of this -- or any other -- computer language.

A loop formula can be calculated as
Math.Round (condition - initialization )/increment
In first case its
(N-0)/1 which evaluates to N times
In second case its
(N-1)/1 which evaluates to N-1 times
In third case its
(N-0+1)/1 which evaluates to N+1 times
How would I do if I need to execute statement between m and n times? For instance I want to call one method between m and n times?
then check it in condition
for (int i = m; i < n; i++)
{
someMethodCall();
}

In for loop you can have these code,
N Time
for (int i = 0; i < N; i++) {
}
N+1 Time
for (int i = 0; i <= N; i++) {
}
And if there isn't any time and you want handle it your self you can use this,
for (;;) {
//do something and don't forget use break or return !
}
OR
while(x>10){
}
and loop in loop is good as Ernest Friedman-Hill said
for (int i = 0; i <=10; i++) {
for (int i = 0; i < length; i++) {
}
}
use 2xTab for visual studio help.

Related

Simplify Selecting 2nd list based on a previous list in C#

I have 2 checked list boxes, where you select the main idea in the first one, and select a narrower focus in the 2nd box. After much work, I finally made it work, but it still seems horribly inefficient. Is there a way to optimize this?
List<int> k= new List<int>();
int f = 0;
for(int j = 0; j < SubRaces.Items.Count; j++) {
if(SubRaces.GetItemCheckState(j) == CheckState.Checked) {
f = j;
}
}
for(int i = 0; i < DNDSubRace.allSubRaces.Count; i++){
if(DNDSubRace.allSubRaces[i].MainRace.Name == Races.SelectedItem) {
k.Add(i);
}
}
DNDSubRace.allSubRaces [k [f]].DNDSubRaceDescription();
SubRaceBenefits.Text = DNDSubRace.allSubRaces [k [f]].Details;
You can optimize the code a little bit, for example you can add a break statement in the first for loop (this requires you to reverse the loop to get the exact same behaviour, provided SubRaces.GetItemCheckState() does not need to be called for every element)
List<int> k = new List<int>();
int f = 0;
for(int j = SubRaces.Items.Count - 1; j >= 0; j--) {
if(SubRaces.GetItemCheckState(j) == CheckState.Checked) {
f = j;
break;
}
}
for(int i = 0; i < DNDSubRace.allSubRaces.Count; i++){
if(DNDSubRace.allSubRaces[i].MainRace.Name == Races.SelectedItem) {
k.Add(i);
}
}
DNDSubRace.allSubRaces [k [f]].DNDSubRaceDescription();
SubRaceBenefits.Text = DNDSubRace.allSubRaces [k [f]].Details;
Another possibility is using Linq which will be slower, but is shorter to write. When using Linq to shorten the above solution, the result is:
List<int> k = DNDSubRace.allSubRaces.Where(r=>r.MainRace.Name == Races.SelectedItem).ToList();
int f = 0;
for(int j = SubRaces.Items.Count - 1; j >= 0; j--) {
if(SubRaces.GetItemCheckState(j) == CheckState.Checked) {
f = j;
break;
}
}
DNDSubRace.allSubRaces [k [f]].DNDSubRaceDescription();
SubRaceBenefits.Text = DNDSubRace.allSubRaces [k [f]].Details;
The first way of optimizing the code is reducing the number of cycles the upper for loop will be run for. When there are two matching elements in SubRaces then the variable f will be set to the index two times and the last match will stay (in the unoptimized version). If you reverse the for loop and exit it as soon as you get a match you will end up with the same behaviour, but it will be quicker.
The second rewrite wraps the second for loop into a Linq statement, which is slower but is shorter to write. Essentially it applies a filter and then copies the matching elements over to a new List.
I hope this helps!
Your answer would be to use events. When the item in the first list gets selected you can populate the second list with only its related options.

Exiting loop without break/return/if

If you have a for loop:
for(i=0;i<10;i++){}
Now, when i==5, how can I exit the for loop completely without using break, return, or if?
The best I could come up with was this:
for (int i = 0; i < 10; i++)
{
i = (i == 5) ? 10 : i;
Trace.WriteLine("i = " + i.ToString());
}
...which will cause the loop to run six times (i=0..5) and display this..
i = 0
i = 1
i = 2
i = 3
i = 4
i = 10
The alternative way to "exit the loop" (in a particularly nasty fashion) would be to do this...
for (int i = 0; i < 10; i++)
{
int a = 3 / ((i == 5) ? 0 : 1);
Trace.WriteLine("i = " + i.ToString());
}
..which crashes out, errr, successfully exits the loop without using the break, return or if commands.
i = 0
i = 1
i = 2
i = 3
i = 4
A first chance exception of type 'System.DivideByZeroException' occurred in MikesProgram.dll
language is C# .it was an interview question actually..curious
Do I get the job ?
I would need to check your health & dental plans, and I have to leave early on Thursdays to collect my daughters from school.
;-)
for (int n = 0; n < 10; n++)
{
n += (n / 5) * 5;
}
well here's another way if you want to break the processing exactly when i = 5 without using break, return, or if
for (int lowsetLimit = 0, highestLimit = 10, i = lowsetLimit; i < highestLimit; i++)
{
//normal code which process before i gets eqaul to 5 goes here...
i = (i < 5) ? i : highestLimit; //and here is the pivot point.
}
for(i=0;i<10;i++){
(i==5) ? goto Outer : //do something;
}
Outer:
//do something
The question says that loop should end when i=5, It says nothing about start, So this should be valid (ternary operator solution is better, but if we are not allowed to use any conditional operator)
for (int i = 0; i < 10; i++)
{
i=i-4;
Console.WriteLine("i = " + i.ToString());
i=i+4;
}
this Starts at -4 and ends at 5.
The real answer of course would be the following:
for (i=0; i!=5; i++)
{
// do something
}
But let's make it a bit more generic: stop if (expression) becomes true.
The second argument of the for loop is a boolean expression which determines whether to continue the loop with the next element or not.
So if you want to stop looping because of any condition:
for (i=0; !(expression) && i<10; i++)
{
// do something
}
This works using while and goto:
for (int i = 0; i < 10; i++)
{
while (i < 5)
{
Console.Write(i + " ");
goto OutsideWhile;
}
OutsideWhile:
continue;
}
// 0 1 2 3 4

For loop in a static method does not need {}

using System;
class FirstArray
{
static void Main()
{
int numOfGrades;
double[] listOfGrades;
Console.Write("How many students in the class? ");
numOfGrades = int.Parse(Console.ReadLine());
listOfGrades = new double[numOfGrades];
ReadGrades(listOfGrades);
double sumGrades = GetGradesSum(listOfGrades);
Console.WriteLine("\n\nClass statistics\n--------------------");
Console.WriteLine("Grades sum = {0:F2}", sumGrades);
}
static void ReadGrades(double[] grades)
{
for(int i = 0; i < grades.Length; i++)
{
Console.Write("Enter the grade of student {0}:", i + 1);
grades[i] = double.Parse(Console.ReadLine());
}
}
static double GetGradesSum(double[] grades)
{
double sum = 0;
for(int i = 0; i < grades.Length; i++)
sum += grades[i];
return sum;
}
}
Hi everyone,
Why does the for loop in the GetGradeSum method not require {}? When I do put the braces in, there is a compile time errors of "unreachable code detected" and "not all code paths return a value. Does it have something to do with the return function?
Thanks in advance!
Why does the for loop in the GetGradeSum method not require {}?
Because its body is a single statement. It's much simpler to understand if you indent your code properly. Your current code is more clearly written as:
static double GetGradesSum(double[] grades)
{
double sum = 0;
for(int i = 0; i < grades.Length; i++)
sum += grades[i];
return sum;
}
Note how the return statement is not part of the loop. If it were, it would return the first grade, rather than the sum.
So the equivalent code with braces is:
static double GetGradesSum(double[] grades)
{
double sum = 0;
for(int i = 0; i < grades.Length; i++)
{
sum += grades[i];
}
return sum;
}
It sounds like you tried to put braces around both statements, so:
// Broken
static double GetGradesSum(double[] grades)
{
double sum = 0;
for(int i = 0; i < grades.Length; i++)
{
sum += grades[i];
return sum;
}
}
At this point, the compiler complains because it's entirely possible to reach the end of the method without returning anything - if grades has a length of 0, we'll never go into the body of the loop, so never return.
Note that LINQ makes all of this irrelevant anyway, mind you - you can just write:
using System.Linq;
...
double sumGrades = listOfGrades.Sum();
If you don't write braces {}, then only the line after the for (...) is executed inside the loop.
Basically:
for (...)
A();
B();
is equivalent to:
for (...)
{
A();
}
B();
This also answers your second question, as the return statement would be inside the loop (assuming you put } after it).
If the loop body consist of only one statement, you can omit the braces. but if you do:
for(int i = 0; i < grades.Length; i++)
{
sum += grades[i];
return sum;
}
In this case there is no guarantee that for loop will run (e.g i < grages.Length might not be true) so you get the error.Instead you should move the return statement outside of the loop.
Braces are not required when there is only one statement to execute.
This code:
for(int i = 0; i < grades.Length; i++)
sum += grades[i];
is equivalent to this code:
for(int i = 0; i < grades.Length; i++)
{
sum += grades[i]
}
If there is more than one statement to execute, braces are required.
On a side note, it is always more clear to use the braces than not to.
Having a for loop without brackets means you're going to apply the 'loop' on the next statement only
So
for(int i = 0; i < grades.Length; i++)
sum += grades[i];
is equivalent to
for(int i = 0; i < grades.Length; i++)
{
sum += grades[i];
}
The indentation in the method is a bit confusing, as it can lead you into thinking that the return statement is part of the loop.
The braces around the code in the loop is only mandatory if you want to put more than one statement in the loop. If you don't have braces, then only the statement following the for clause is part of the loop.
If you add the braces for the loop, they should be only around the statement after the loop:
static double GetGradesSum(double[] grades)
{
double sum = 0;
for(int i = 0; i < grades.Length; i++)
{
sum += grades[i];
}
return sum;
}
If you instead included the return statement inside the loop, then it would only be executed if the code inside the loop was executed, so you get a compiler error telling you that it's guaranteed that the return statement is executed.
Quite Simply, all the answers here are accurate. In most languages that parallel C,
you do NOT need curly braces if you're targeting a single statement .
Meaning the VERY NEXT LINE after you initiate the for loop is the only statement included within the for loop.
If you put Braces around your return statement, you'll receive the compile error as you're including the return statement as part of the for loop.
Again, You can include braces around the singular targeted statement if you'd like as a programming aesthetic, but it's not required unless you have multiple statements you want to include within your loop.
This principle is the same for if/else statements.

Algorithm time complexity for various nested for loops

I have a question regarding this SO post: Understanding How Many Times Nested Loops Will Run
In there the general formula for 3 nested for loops is: n(n+1)(n+2)/3. I don't really know why the 2nd inner loop runs n+1 times while the outer loop runs n times (wouldn't the inner loop run once more before it exits out of the for loop? Either way...the general formula is
n(n+1)(n+2)...(n+r-1)
---------------------
r!
Here, r is the number of nested loops.
I am wondering if this formula is always the same for nested loops or if it changes based on what the comparison is inside the for loops...If it is based on comparison then how can I determine the formula if on an exam I am given some different for loops? How can I generate or come up with this formula if the comparison for the for loops is not the same as the comparison in the SO post which creates that formula?
You'll have to train your mind to recognize and follow the patterns in execution, and come up with a formula for specific situations. The general rule of thumb is that if one for loop will run the code inside of it x times, and it has a loop inside of it that will run y times, then the code inside the inner loop will run x*y times.
The most common type of for loop starts at zero and increments by 1 until it reaches a certain number, like so:
for(int i = 0; i < x; i++)
for(int j = 0; j < y; j++)
for(int k = 0; k < z; k++)
// code here runs x * y * z times
To answer your question, if you change any part of any of the for loops, it will change the number of times the inner code is executed. You need to identify how many times that will be by thinking about the logical code execution.
for(int i = 1; i < x; i++)
for(int j = 0; j < y * 2; j++)
for(int k = 0; k < z; k += 2)
// code here runs (x - 1) * (y * 2) * (z / 2) times
In the above example, each for loop is tweaked in a different way. Notice how the overall formula for the number of times run stays pretty much the same, but now each loop is running a different number of times each time it gets hit.
Things become more complicated when the loops' variables affect more than one loop.
for(int i = 0; i < x; i++)
for(int j = i; j < y; j++) // notice how `j` starts as `i`
// Code here runs `y` times the first time through the outer loop,
// then `y - 1` times,
// then `y - 2` times,
// ...
// if x < y, the pattern continues until the xth time,
// when this loop runs `y - x` times.
// if x > y, the pattern will stop when y == x, and
// code here will run 0 times for the remainder of
// the loops.
So in this last example, assuming x < y, the loop will run y + (y-1) + (y-2) ... + (y-x) times.
It changes based on the inner values.
Example.
for (int i = 0; i < 100; i++)
{
//this loop will run 100 times.
for (int i1 = 0; i1 < 100; i++)
{
// This will run 100 times every outer loop int.
// This means that for each index i in the outer loop this will run 100 times.
// The outer loop runs 100 time and this runs 10,000 times in total.
}
}
for (int i = 0; i < 100; i++)
{
//this loop will run 100 times.
for (int i1 = 0; i1 < 10; i++)
{
// This will run 10 times every outer loop int.
// This means that for each index i in the outer loop this will run 10 times.
// The outer loop runs 100 time and this runs 1,000 times in total.
}
}
An easier way to look at it may be this.
for (int i = 0; i < 10; i++)
{
//this loop will run 10 times.
Console.WriteLine("int i = " + i.ToString()");
for (int i1 = 0; i1 < 10; i++)
{
// This will run 10 times every outer loop int.
// This means that for each index i in the outer loop this will run 10 times.
// The outer loop runs 10 time and this runs 100 times.
Console.WriteLine("int i2 = " + i2.ToString()");
}
}
That will output this.
int i = 0
int i2 = 0
int i2 = 1
int i2 = 2
int i2 = 3
int i2 = 4
int i2 = 5
int i2 = 6
int i2 = 7
int i2 = 8
int i2 = 9
int i = 1
int i2 = 0
int i2 = 1
int i2 = 2
int i2 = 3
int i2 = 4
int i2 = 5
int i2 = 6
int i2 = 7
int i2 = 8
int i2 = 9
and so on.
The formula is based on the inner loop numbers. (On when the loop ends.)

Is there a more efficient method for omitting for loop instances

If I have a standard for loop is there a more efficient way to omit certain occurances?
For example:
A:
for (int i = 0; i < n; i++)
{
if (i != n / 2 && i != n / 3 && i != n / 4)
{
val += DoWork(i);
}
else
{
continue;
}
}
B:
for (int i = 0; i < n / 4; i++)
{
val += DoWork(i); ;
}
for (int i = n / 4 + 1; i < n / 3; i++)
{
val += DoWork(i);
}
for (int i = n / 3 + 1; i < n / 2; i++)
{
val += DoWork(i);
}
for (int i = n / 2 + 1; i < n; i++)
{
val += DoWork(i);
}
C:
for (int i = 0; i < n; i++)
{
if (i == n / 2 || i == n / 3 || i == n / 4)
{
continue;
}
else
{
val += DoWork(i);
}
}
For n = int.MaxValue the results were as follows:
A Results: 57498 milliseconds.
B Results: 42204 milliseconds.
C Results: 57643 milliseconds.
EDIT BASED ON #Churk 's answer.
I added another test case method D as follows:
D:
for (int i = 0; i < n; i = (i != n / 2 -1 && i != n / 3 -1 && i != n / 4-1) ? i+1: i+2)
{
val += DoWork(i);
}
and got the following results:
A Results: 56355 milliseconds.
B Results: 40612 milliseconds.
C Results: 56214 milliseconds.
D Results: 51810 milliseconds.
Edit2: After pre-calculating values for n/2 n/3 and n/4 outside the loop got:
A Results: 50873 milliseconds.
B Results: 39514 milliseconds.
C Results: 51167 milliseconds.
D Results: 42808 milliseconds.
The D loop seems to be close again to the "unrolling" of B, with A and C still taking significantly more time.
Which are about what I expected, as far as comparisons between each of the methods.
My question is, is there a more efficient way of doing this?
It depends a bit on the context. One possiblitiy in many scenarios is to cheat. So instead of omitting the numbers, just include them and later reverse the result from the numbers you didn't want:
for (int i = 0; i < n; i++)
{
val += DoWork(i);
}
val -= DoWork(i/2);
val -= DoWork(i/3);
val -= DoWork(i/4);
The time you save from comparisons might outweigh the results from calculating some numbers twice, depending on how expensive the DoWork operation is.
Embed your secondary condition into you for loop
Untested:
for (int i = 0; i < n || (i != n / 2 && i != n / 3 && i != n / 4); i++)
val += DoWork(i);
}
I think this will work as long as one of those condition is true it will keep going
First, just pause it a few times during that 40-60 seconds, so you get a fair idea what fraction of time is in DoWork. If you could even make your looping take no time at all, you'd still have to spend that part.
Now look at your comparisons.
Each one is asking a question.
If the answer to a question is almost always True or almost always False, it is an opportunity to get speedup.
(All the log(n) and n*log(n) algorithms work by making their decision points more like fair coins.)
So you can see why your B is faster. It is asking fewer questions per loop, on average.
You can make it even faster, by unrolling the loops (asking the questions even less often).
(I know, I know, compilers can unroll loops. Well, maybe. Do it yourself and you won't have to bet on it.)
You could calculate the values outside of the loop and then just skip them:
int skip1 = n/2;
int skip2 = n/3;
int skip3 = n/4;
for (int i = 0; i < n; i++)
{
if (i != skip1 && i != skip2 && i != skip3)
{
val += DoWork(i);
}
}
Not sure if this will save enough milliseconds to be worthwhile, though.
Update: I've just noticed that #surfen suggested this in the comments.
If DoWork() isn't the bottleneck, it is a small enough method to embed into the loop, so you won't need the call which costs time by itself. If DoWork() does most of the work though, you're the one wasting time :)
You can count operations...
Option A:
n checks on i in the for loop and then 3 checks on each i that isn't that value... so there's 4n operations just for the checks.
option B:
You're just looping through intervals, so you're doing n-3 operations.
option C:
Same as option A, 4n operations.
I wouldn't bother complicating code with such modifications (as many have already commented on your question)
Instead, you might want to run your DoWork simultanuously in multiple threads using Pararell.ForEach. This would have a much larger impact on performance, if your DoWork() does anything.

Categories

Resources