It's to prevent fencepost errors, aka "off-by-one".
Common exam question:
You are required build 100 meters of fence, with a fence post every meter. How many fenceposts will you need?
Obvious quick (and WRONG) answer:
100 meters
--------------- = 100 posts
1 post
------
meter
Because for 100 meters of fence, you need 101 posts:
Distance: 1 2 .... 99 100
|-|-|.....| - | - |
Post: 1 2 3 ....99 100 101
Now with arrays, the same thing happens. Let's say it's an array with 5 items:
for (i = 0 ; i <= 5; i++)
^--length of array
You end up doing
i: 0, 1, 2, 3, 4, 5
iteration: 1 2 3 4 5 6
Oops. 5 item array, but you've executed your loop 6 times - one times too many.
You can fix the error in two ways:
for (i = 0; i < length; i++)
^---change from "<=" to "<"
or
for (i = 0; i <= length - 1; i++)
^---change the upper limit value.
Answer from Marc B on Stack OverflowIt's to prevent fencepost errors, aka "off-by-one".
Common exam question:
You are required build 100 meters of fence, with a fence post every meter. How many fenceposts will you need?
Obvious quick (and WRONG) answer:
100 meters
--------------- = 100 posts
1 post
------
meter
Because for 100 meters of fence, you need 101 posts:
Distance: 1 2 .... 99 100
|-|-|.....| - | - |
Post: 1 2 3 ....99 100 101
Now with arrays, the same thing happens. Let's say it's an array with 5 items:
for (i = 0 ; i <= 5; i++)
^--length of array
You end up doing
i: 0, 1, 2, 3, 4, 5
iteration: 1 2 3 4 5 6
Oops. 5 item array, but you've executed your loop 6 times - one times too many.
You can fix the error in two ways:
for (i = 0; i < length; i++)
^---change from "<=" to "<"
or
for (i = 0; i <= length - 1; i++)
^---change the upper limit value.
If your array has 4 elements, for example
var elementOfArray = [7, 9, 0, 2]
and you want to reach those elements. In that case, you need to know that elementOfArray[i] represents element of your array and i is the index.
For that reason, if you add '-1' on your array length; you can see whole elements in your array like elementOfArray[0]---7, elementOfArray[1]---9, elementOfArray[2]---0, elementOfArray[3]---2. See! you took the whole number in the element.
If you do not subtract 1 of array length, you would take an error. Because there is no elementOfArray[4] that represents any element of your array.
I'm going through JavaScript Algorithms and Data Structures Masterclass. One of the problems the instructor gave has got me a little confused. I was hoping someone could enlighten me.
function sumZero(arr) {
let left = 0;let right = arr.length - 1;
while (left < right){
let sum = arr[left] + arr[right];
if (sum === 0){
return [arr[left], arr[right]];
} else if (sum > 0){
right--;
} else {
left++;
}
}
console.log(left, right)
}
sumZero ([-4,-3,-2,-1,0,1,2,3,10])I think the arr.length - 1 is supposed to start a loop starting on the number furthest right of loop but if that is the case I'm not sure how the arr.length - 1 makes that happen? Anybody got any clarity regarding this?
This
for(let i = 0; i < array.length; i++){...}
loops from indicies 0 to array.length - 1. For example, with an array with 3 items, this iterates over is of 0, 1, and 2.
This
for(let i = 0; i < array.length + 1; i++){...}
is strange. It loops from indicies 0 to array.length. For example, with an array with 3 items, this iterates over is of 0, 1, 2, and 3. This means that if something inside the loop references array[i], that value will be undefined on the final iteration.
Most of the time, seeing something like that would make me think someone made a typo or logic error - though I wouldn't be surprised to see a few algorithms that used something like it.
This
for(let i = 1; i < array.length; i++)
iterates from indicies 1 to array.length - 1. For example, with an array with 3 items, this iterates over is of 1, and 2.
There will be one less iteration than elements in the array. This means that, if the loop body always references array[i], and not array[i - 1], then the first element in the array will always be skipped over.
This is much less common than starting at 0, but could be seen, especially when the logic requires comparing certain adjacent elements against each other (for example, array[0] to array[1], and array[1] to array[2], and so on).
Array.length + 1
simply put is just the number of elements in the array and add 1.
An array with n elements has a length of n , so your loop will run n - i times when using array.length. If let i =0 , then your loop will run n times. If i = 1 , then your loop will run n-1 times if using array.length. So you will be missing 1 iteration of your loop.
If you need to use i=1 to start your iterations, you should use array.length +1 to get the equivalent number of iterations.
for(let i =0;i<array.length;i++){} // n iterations
is the same number of iterations as
for(let i= 1;i<array.length +1;i++){} // n iterations
for(let i=1;i<array.length;i++){} // n-1 iterations
will always be 1 less iteration.
And remember, Array indexing uses a 0-based counter, so array[0] is the first element of every array.