How to find MAX number in unseen array using for loop? - javascript

This is the solution to the problem. What I don't understand is why is it not "if ( i > currentMax)? I also don't understand the nature of numbers[i]. I understand we can reference indexes in arrays doing numbers[0], but numbers[i] is confusing me.
function max(numbers) {
let currentMax = numbers[0];
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] > currentMax) {
currentMax = numbers[i];
}
}
return currentMax;
}

numbers[i] refers to the value stored at position i. If you were to use if (i > currentMax) then you would always return the last element, since the last element always has the greatest index.
Don't reinvent the wheel, use Math.max(...numbers).

Say you have an array like:
[1, 2, 4, 2]
This starts by setting currentMax numbers[0] which is one. Then it loops through the array one element at a time. If it finds a larger number during that loop — in other words if (numbers[i] > currentMax) then it sets the currentMax that number instead. For example this will happen the second and thirds times through the loop when i equals 2 & 4. But it won't happen the last time through the loop. An easy way to watch this happen is to print some stuff to the console as it runs:
function max(numbers) {
let currentMax = numbers[0];
for (let i = 0; i < numbers.length; i++) {
console.log("i:", i, "element:", numbers[i], "max:", currentMax)
if (numbers[i] > currentMax) {
currentMax = numbers[i];
console.log("new currentMax:", currentMax)
}
}
return currentMax;
}
max([1, 2, 4, 2])

In this case i is an "index" which allows us to iterate over all the positions in the array (and accessing their values). In this case i=0, i=1,..., i=numbers.length,
if (numbers[i] > currentMax) asks if the number stored in the array in the position i is greater than the currentMax value. This guarantees that from the provided array the maximum number is returned.
If you ask if (i > currentMax) you compare the value of the "index" (i) with the value of the currentMax value. This is incorrect if you want to return the greatest value from an array of numbers.

Like you said, you can reference indexes in arrays by doing numbers. Instead of hard coding numbers you can use a variable that has a number as a value.
function max(numbers) {
// get the value in the first place in the array
let currentMax = numbers[0];
// create a variable called i
// set it to 0
// loop through, increasing i each time, for as long as i is less than the length of the array
// the first time through i = 0
// the second time through i = 1
// then i = 2
// ... repeat until the end
for (let i = 0; i < numbers.length; i++) {
// get the value from the array at the i place
// if it is greater than the current max
if (numbers[i] > currentMax) {
// then set current max to it
currentMax = numbers[i];
}
}
// return current max
return currentMax;
}

Related

How do I write a for loop that decrements the iterator while outputting numbers in ascending order

In the following for loop, how do I loop backwards and return all even numbers?
// How do I write a for loop that decrements the iterator while
// outputting numbers in ascending order: 2, 4, 6, 8, 10
for (let i = 0; i < 11; i--) {
if (i !==3,5,7,9){
console.log(i);
}
}
You need to change the condition to reflect the expected output:
for (var i = 2; i < 11; i += 2) {
console.log(i);
}
The current for loop in the above snippet start at 0 and starts decrementing from the same, leading to negative value indexes.
Just start the loop's index at 11 and decrement from that index while checking if each index is an even number or not using a modulus operator like this index % 2 == 0.
Log all even numbers as a single string:
If the value is an even number, append it to the beginning of a string called say, even and then simply log each element in the even array to your console like this:
var even = ""; //assign an empty string for your even numbers
for (let i = 11; i > 0; i--) { // loop through all numbers between 0 and 11
if (i % 2 == 0) { // check each loop value if it's an even number or not
even = i + ", " + even; // append the even numbers to the start of your "even" string
}
}
// log each element in your "even" string to the console
console.log(even);
Log every ascending even number as a separate integer:
If the value is an even number, push it to the beginning of an array called say, even using the unshift() method and then simply log each element in the even array to your console like this:
var even = []; //assign an empty array for your even numbers
for (let i = 11; i > 0; i--) { // loop through all numbers between 0 and 11
if (i % 2 == 0) { // check each loop value if it's an even number or not
even.unshift(i); // add the even numbers to the start of your "even" array using the unshift() method
}
}
// log each value in your "even" array to the console
even.forEach(e => console.log(e));

Algorithm: Next Greater Element I (from leetcode)

can someone please tell me what I'm missing in solving this algorithm? One problem I have is that my first if statement inside the nested loop is not evaluating, but I don't know why it wouldn't evaluate.
Here is the description of the problem:
You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of nums2. Find all the next greater numbers for nums1's elements in the corresponding places of nums2.
The Next Greater Number of a number x in nums1 is the first greater number to its right in nums2. If it does not exist, output -1 for this number.
Example 1:
Input: nums1 = [4,1,2], nums2 = [1,3,4,2].
Output: [-1,3,-1]
Explanation:
For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1.
For number 1 in the first array, the next greater number for it in the second array is 3.
For number 2 in the first array, there is no next greater number for it in the second array, so output -1.
link to original description
And here is my code so far:
var nums1 = [4,1,2];
var nums2 = [1,3,4,2];
var nextGreaterElement = function(findNums, nums) {
var holder = [];
for (var i = 0; i < findNums.length; i++) {
//loop through the 2nd array starting at the index of the first loop's current item.
for (var j = nums.indexOf(findNums[i]); i < nums.length - j; i++) {
if (nums[j+1] > nums[j]) {
holder.push(nums[j+1]);
break;
}
if (nums[nums.length]) {
holder.push(-1);
}
}
}
return holder;
};
nextGreaterElement(nums1, nums2)
Thanks for any help.
Problem: Updating variant i, but not variant j in inner loop (j-loop)
Missing: Debugging Effort
Problem Description
Theoretically, your code design should compare each value in nums1 to related parts of nums2. So, it would turn to a outer for-loop to loop on nums1 and an inner for-loop to loop related parts of nums2 for each iteration of the outer for-loop.
In your code, variant i is the index pointer for findNums (i.e. nums1) while variant j is the index pointer for nums (i.e. nums2). Variant i is always updating in both inner for-loop and outer for-loop while variant j is set once for every iteration of outer for-loop. This contradict to what you are suppose to do.
Debugging (Your Missing Work)
Find a piece of paper and a pen. Sit down, dry run the program and keep recording related info (variant i, variant j, findNums[i], nums[j], ...), you could figure out why your code is not working.
Possible Solution
var nextGreaterElement = function(findNums, nums) {
var holder = [];
for (var i = 0; i < findNums.length; i++) {
var hasNextGreaterElement = false;
// try to serach for next greater element
for (var j = nums.indexOf(findNums[i])+1; j < nums.length; j++) {
// handle case for next greater element is found
if (nums[j] > findNums[i]) {
holder.push(nums[j]);
hasNextGreaterElement = true;
break;
}
}
// handle case for next greater element is not found
if (!hasNextGreaterElement) {
holder.push(-1);
}
}
return holder;
};
var findNums=[4,1,2];
var nums=[1,3,4,2];
console.log(nextGreaterElement(findNums, nums));
You need to sort the array you are looking in to make it easier to find the number. If the array get big you might want a search algorithm to find the index in the array faster. With the array that is going to be looked in sorted you can grab the next number as the number that is one larger and check to see if you are at the end of the array. If you don't do this check the function will error when you can't find the number or when there is no number larger. Finally your second if statement didn't make sense. So I am checking to make sure that we are at the end of the array before outputting the -1 in the array.
var nextGreaterElement = function(findNums, nums) {
var holder = [];
//Should sort the array to make sure you get the next largest number
nums = nums.sort();
for (var i = 0; i < findNums.length; i++) {
//loop through the 2nd array starting at the index of the first loop's current item.
//for (var j = nums.indexOf(findNums[i]); i < nums.length - j; i++) {
for(var j = 0; j < nums.length; j++){
//check for value in array and make sure the value is not at the end
if (findNums[i] == nums[j] && j != nums.length - 1) {
holder.push(nums[j+1]);
break;
}
//check for the last element in array if so output -1
if (j == nums.length - 1) {
holder.push(-1);
}
}
}
return holder;
};

Insertion Sort Algorithm on JavaScript

I recently started learning algorithms based on the book Data Structures and Algorithms with JavaScript from O'Reilly.
I stopped on Chapter 12 - Sorting Algorithms.
I can not understand how Insertion Sort works.
Here is the code I am working with: pasteBin - Insertion Sort
Below is the part that is confusing to me:
function insertionSort() {
var temp, inner;
for (var outer = 1; outer <= this.dataStore.length - 1; ++outer) {
temp = this.dataStore[outer];
inner = outer;
while (inner > 0 && (this.dataStore[inner-1] >= temp)) {
this.dataStore[inner] = this.dataStore[inner-1];
--inner;
}
this.dataStore[inner] = temp;
}
console.log(this.toString());
}
Could anyone help and comment on this code?
It's a sorting algorithm which starts at the beginning of the array and passes through until the end. For the item at each index, it goes back through the items at earlier indices and checks to see if it should be placed before them. If so, it swaps indices with the larger value until it settles into the index it should have.
Here's the code with some commentary, hopefully it is helpful to you.
function insertionSort() {
/* Set up local vars */
var temp, inner;
/* Start at index 1, execute outer loop once per index from 1 to the last index */
for (var outer = 1; outer <= this.dataStore.length - 1; ++outer) {
/* Store the value at the current index */
temp = this.dataStore[outer];
/* Set up temporary index to decrement until we find where this value should be */
inner = outer;
/* As long as 'inner' is not the first index, and
there is an item in our array whose index is less than
inner, but whose value is greater than our temp value... */
while (inner > 0 && (this.dataStore[inner-1] >= temp)) {
/* Swap the value at inner with the larger value */
this.dataStore[inner] = this.dataStore[inner-1];
/* Decrement inner to keep moving down the array */
--inner;
}
/* Finish sorting this value */
this.dataStore[inner] = temp;
}
console.log(this.toString());
}
Here is a jsfiddle with lots of console printouts so you can step through it and see what happens at each step.
The main concept behind insertion sort is to sort elements by comparison.
The comparison occurs in your case for a dataStore array, containing what we assume to be comparable elements such as numbers.
In order to compare element by element, this insertion sort algorithm starts at the beginning of the dataStore array and will continue to run until the end of the array has been reached. This is accomplished by a for loop:
for (var outer = 1; outer <= this.dataStore.length - 1; ++outer)
As the algorithm goes through each element in order, it will:
Store the current element we are visiting in the array in a variable called temp.
Keep track of the location we are in the array via the inner and outer variables, where:
outer is our counter.
inner is a flag to determine whether or not we are visiting the first element in the array. Why is this important? Because there is no point in doing a comparison on the first element, on the first try.
It will compare the current element temp with each element that came before it in the dataStore array. This is accomplished by an inner while loop as seen here:
while (inner > 0 && (this.dataStore[inner-1] >= temp))
This tells you that, as long as all previous visited elements in the dataStore array are greater than or equal to temp, our temporary variable used to store the current element; we want to swap these values.
Swapping them will accomplish the following:
Assume all elements before this.dataStore[inner] are greater than 10, and the currently visited element this.dataStore[inner] equals 5. This logically means that 5 needs to be at the beginning of the array. In such case we would continue to pass 5 all the way down to this.datastore[0] thanks to the while loop. Thus making 5 the first element in the array.
At the end of this swapping, the value in temp is placed accordingly to the current position we are in the array, just to remind you which position this is, it's stored the variable outer.
TLDR: I also like Justin Powell's answer as it sticks with the code, but I thought a walk through would be more useful depending on your level of understanding. I hope it helps!
Starting from the inner loop check if the current element is greater than the previous if yes, exit the loop since everything is sorted for the iteration, if not swap elements because the current needs to be moved to the left because it's smaller than the previous. The inner loop makes sure to swap elements until you encounter a sorted element which results with the break exiting the loop.
After the swap occurs decrease the outer index (i) since you are going downwards to check if the upcoming element is lesser than the previous, you cannot keep the outer index (i) static.
At last, the memIndex variable serves as a reset index because at the end of your inner loop you want to move to the next index. Index (i) should always be placed at the last element of the sorted array so that the inner loop can start the comparison again.
function insertionSort(arr) {
let memIndex = 0
for (let i = 0; i < arr.length; i++) {
memIndex = i;
for (let j = i + 1; j >= 0; --j) {
if (arr[j] >= arr[i]) {
break;
}
if (arr[j] < arr[i]) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i = i - 1;
}
}
i = memIndex;
}
return arr;
}
const arr = [5, 1, 6, 2, 4, 9, 9, 3, 1, 1, 1];
console.log('Unsorted array', arr);
console.log('Sorted array:', insertionSort(arr));
const insertionSort = array => {
const arr = Array.from(array); // avoid side effects
for (let i = 1; i < arr.length; i++) {
for (let j = i; j > 0 && arr[j] < arr[j - 1]; j--) {
[arr[j], arr[j - 1]] = [arr[j - 1], arr[j]];
}
}
return arr;
};
insertion sort means first step we are going to take one value from unsorted sublets and second step we are going to find out appropriate place for that in sorted sublet after find out right place we will insert that value in sorted sublet.
you can get deep understanding from this video links:-
Insertion Sort Algorithm | Data Structure
function insertionSort(arr) {
for (let i = 1; i < arr.length; i++) {
// first step
let currentValue = arr[i]
let j
for (j = i - 1; j >= 0 && arr[j] > currentValue; j--) {
// second step
arr[j + 1] = arr[j]
}
arr[j + 1] = currentValue
}
return arr
}
console.log(insertionSort([5,2,6,3,1,4]))

Is this the right way to iterate through an array?

Here is the code in question:
var L1 = [];
var Q1 = [];
function populateListOne() {
var limit = prompt("please enter a number you would like to fill L1 to.");
for (i = 2; i <= limit; i++) {
L1[i] = i;
}
for (n = 2; n <= L1.length; n++) {
var count = 2;
if (n == count) {
var index = L1.indexOf(n);
L1.splice(index, 1);
Q1[n] = n;
count = count + 1;
}
for (j = 0; j <= L1.length; j++) {
if (L1[j] % 2 == 0) {
var secondIndex = L1.indexOf(j);
L1.splice(secondIndex, 1);
}
}
}
document.getElementById("demo").innerHTML = "iteration " + "1" + ": " + L1 + " Q1 = " + Q1;
}
I’m currently working on a homework assignment where I have to setup a queue. All is explained in my JSFiddle.
Problem description
Essentially, the part I’m stuck on is iterating through each instance of the array and then taking the value out if the modulus is identical to 0. However, as you can see when I run the program, it doesn’t work out that way. I know the problem is in the second for loop I just don’t see what I’m doing wrong.
The way I read it is, if j is less than the length of the array, increment. Then, if the value of the index of L1[j] modulus 2 is identical to 0, set the value of secondIndex to whatever the index of j is. Then splice it out. So, theoretically, only numbers divisible by two should be removed.
Input
A single number limit, which will be used to fill array L1.
L1 will be initialized with values 2, 3, ... limit.
Process
Get the starting element of array L1 and place it in array Q1.
Using that element, remove all values in array L1 that are divisible by that number.
Repeat until array L1 is empty.
You're going to have issues with looping over an array if you're changing the array within the loop. To help with this, I tend to iterate from back to front (also note: iterate from array.length - 1 as the length element does not exist, arrays are key'd from 0):
for(j = L1.length - 1; j >=0 ; j--)
For your first loop, you miss the elements L1[0] and L1[1], so I would change the first loop to:
L1 = [];
for(i = 2; i <= limit; i++)
{
L1.push(i);
}
In this section:
for(j = 0; j <= L1.length; j++){
if(L1[j] % 2 == 0)
{
var secondIndex = L1.indexOf(j);
L1.splice(secondIndex, 1);
}
}
you should splice with j instead of secondIndex.
Change L1.splice(secondIndex, 1); to L1.splice(j, 1);
Array indices and putting entries
You initial code used an array that was initialized to start at index 2. To avoid confusion, of what index to start at, start with index 0 and iterate until array.length instead of a predefined value limit to ensure that you go through each element.
The following still works but will be more of a headache because you need remember where to start and when you will end.
for (i = 2; i <= limit; i++) {
L1[i] = i; // 'i' will begin at two!
}
Here's a better way:
for (i = 2; i <= limit; i++) {
// 'i' starts at 2 and since L1 is an empty array,
// pushing elements into it will start index at 0!
L1.push(i);
}
Use pop and slice when getting values
When you need to take a peek at what value is at the start of your array, you can do so by using L1[0] if you followed my advice above regarding array keys.
However, when you are sure about needing to remove the starting element of the array, use Array.slice(idx, amt). idx specifies which index to start at, and amt specifies how many elements to remove beginning at that index (inclusive).
// Go to 1st element in L1. Remove (1 element at index 0) from L1.
var current = L1.splice(0, 1);
Use the appropriate loops
To make your life easier, use the appropriate loops when necessary. For loops are used when you know exactly how many times you will iterate. Use while loops when you are expecting an event.
In your case, 'repeat until L1 is empty' directly translates to:
do {
// divisibility checking
} while (L1.length > 0);
JSFiddle
Here's a complete JS fiddle with in-line comments that does exactly what you said.

Javascript Averages

I am trying to learn Javascript. I've built the following code to find the average from an array of numbers. It works except the last returned value is always NaN. I cannot figure out why. If I move this piece outside of the block it seems to forget altogether what the variable sum is supposed to be equal to. Is there some kind of global-variable type equivalent I'm supposed to be using for JS?
var average = function(myarray) {
sum = 0;
for (counter = 0; counter <= myarray.length; counter++) {
sum = sum + myarray[counter];
average = sum / myarray.length;
console.log(average);
};
}
average([1, 2, 3])
Change
counter <= myarray.length
to
counter < myarray.length
because indexes start at 0.
Full example:
var average = function(myarray) {
var sum = 0;
for (var counter = 0; counter < myarray.length; counter++) {
sum += myarray[counter];
}
return sum / myarray.length;
}
console.log(average([1,2,3]));
JSBin Demo: http://jsbin.com/siyugi/1/edit
myarray[myarray.length] is undefined, which intoxicates your computation with NaN(Not A Number).
Just change it to
for(counter = 0; counter < myarray.length; counter ++) {
// ...
}
Since you are just learning you should know it is good practice to not use .length in a for loop like that. It causes the code to have to check the length of your array on each loop. And remember that .length is returning the number of elements in the array; but array index starts at 0.
for(var counter = 0, length = myarray.length; counter < length; counter++){
}
Would be the proper way to do it.
Don't use variables without declaring them with var keyword, otherwise they will become global properties.
The JavaScript Arrays are zero index based arrays. So, if the size of the array is 3, then the first element will be accessed with 0 and the last with 2. JavaScript is very forgiving, so when you access an element at an invalid index in the array, it will simply return undefined.
In the iteration, you are replacing the current function object with the average value. So, subsequent calls to average will fail, since average is not a function object any more.
It is a good practice to have a function return the computed value, instead of printing the value, so that it will not violate the Single Responsibility Principle.
In your case,
for (counter = 0; counter <= myarray.length; counter++) {
The counter runs till the last index of the array + 1. Since it returns undefined in the last iteration, JavaScript returns NaN in the arithmetic operation.
console.log(1 + undefined);
# NaN
So, you need to change the code, like this
function Average(myarray) {
var sum = 0, counter;
for (counter = 0; counter < myarray.length; counter++) {
sum = sum + myarray[counter];
}
return sum / myarray.length;
}
If you are interested, you can compute the sum with Array.prototype.forEach, like this
function Average(myarray) {
var sum = 0;
myarray.forEach(function(currentNumber) {
sum += currentNumber;
});
return sum / myarray.length;
}
Even better, you can calculate the sum with Array.prototype.reduce, like this
function Average(myarray) {
return myarray.reduce(function(sum, currentNumber) {
return sum + currentNumber;
}, 0) / myarray.length;
}
You can calculate the average of an array of numbers as follows:
var avg = c => c.reduce((a,b) => a +b) / c.length;
avg([1,2,3])

Categories

Resources