1

I'm trying to run a program called IsSubArray. There are 2 input textboxes. One is called the big array and the other is called the sub array. The task is to check whether the values in sub array consecutively matches the numbers in big array. For example:

Array 1: 1,3,6,5,4

Array 2: 1,3,6 - true because 1,3 is matching with array 1.

Array 2: 1,6 - false because after 1, its 3 in array 1 not 6. It should match consecutively.

Array 2: 6,5,4 - true.

Array 2: 5,4,7 - false because is no number 7 after 4 in array 1. But I am getting true for this last statement. I am unable to figure out why. I am just now learning algorithms.

Thanks in advance :)

function IsSubArray() {
    inputArray1 = document.getElementById("inputText1").value.split(",");
    inputArray2 = document.getElementById("inputText2").value.split(",");
    var k = 0;
    var msg = false;
    for (j = 0; j < inputArray2.length - 1; j++) {
        if (j > 0 && msg == false)
            break;
        //if (j > 0 && k == 0) {
        //    msg = false;
        //    break;
        //}
        for (i = 0; i < inputArray1.length - 1; i++) {
            if (inputArray2[j] == inputArray1[i] && inputArray2[j + 1] != inputArray1[i + 1]) {
                msg = false;
                break;
            }
            else if (inputArray2[j] == inputArray1[i] && inputArray2[j + 1] == inputArray1[i + 1]) {
                msg = true;
                break;
            }
            //if (inputArray2[j] == inputArray1[i])
            //    k = 1;
        }
    }
    document.getElementById("output").value = msg + " : LongArray: " + inputArray1 + " , ShortArray: " + inputArray2;
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <input id="inputText1" type="text" />
    <input id="inputText2" type="text" />
    <br /><br />
    
    <input id="IsSubArrayBtn" type="button" value="IsSubArray" onclick="IsSubArray()" />
    <br /><br />
    
    <input id="output" type="text" />
    <script src="js/LogicalLoopings.js"></script>
</body>
</html>
  • Yes. Its false because in array 1, the next number after 1 is 3 and not 6. Whereas in array 2 its 1,6. 1,3 doesn't match with 1,6. Therefore its false. – Vaibhav Shankar Oct 25 '18 at 22:12
  • Ah, consecutive means "consecutive", not just "after", of course, my mistake :) – CertainPerformance Oct 25 '18 at 22:12
  • 1
    Possible duplicate of [Javascript array contains/includes sub array](https://stackoverflow.com/questions/34151834/javascript-array-contains-includes-sub-array) – Olian04 Oct 25 '18 at 22:13
  • Your implementation is flawed in multiple ways. Besides the issue you discovered, which is likely related to the fact that you are not iterating over the last element (`j < inputArray2.length - 1`), your implementation also exists too early when there is a partial match: `false : LongArray: 1,3,6,1,3,4 , ShortArray: 1,3,4` – Felix Kling Oct 25 '18 at 22:51

2 Answers2

1

The code seems overly complex. The general approach would be:

  • Find first element of subarray in array to get a starting point.
  • Verify that every element in subarray matches the following elements in array (at the starting point).
  • Repeat until there are no elements left to check.

Example implementation:

function contains(arr, subarray) {
  const first = subarray[0];
  // labeled loop so we can jump there easily
  // find the "next" starting point for comparing the sequences
  outer: for (let i = arr.indexOf(first); i > -1; i = arr.indexOf(first, i+1)) {
    // When we find a starting point, compare the remaining elements in subarray
    for (let j = 1; j < subarray.length; j++) {
      if (arr[i+j] !== subarray[j]) {
        // no need to continue checking the current sequence
        // if one of the elements doesn't match
        continue outer;
      }
    }
    // if we made it through the inner loop then the sequences must be equal
    return true;
  }
  // if we get here then `subarray` is not a sequence in `arr`
  return false;
}

const arr = [1,3,6,5,4];
console.log(contains(arr, [1,3,6]));
console.log(contains(arr, [1,6]));
console.log(contains(arr, [6,5,4]));
console.log(contains(arr, [5,4,7]));

Array 2: 5,4,7 - false because is no number 7 after 4 in array 1. But I am getting true for this last statement. I am unable to figure out why.

You can add log statements to your code and see what actually happens. The problem is related to the fact that you are never iterating over all elements (i < inputArray1.length - 1) and that you are setting msg to true whenever two consecutive elements match.

The input is:

inputArray1 = [1,3,6,5,4]
// index i     0 1 2 3 4
inputArray2 = [5,4,7]
// index j     0 1 2

At some point you are comparing

 inputArry2[0] == inputArry1[3] && inputArry2[1] == inputArry1[4]
 // 5 == 5 && 4 == 4

which is true, so you set msg to true. Now the inner loop is done, because it stops when i === 3.

A new outer loop starts, where j = 1, so inputArry1[j] === 4. The first part of your if condition (inputArry2[j] == inputArry1[i]) is never fulfilled because i never has the value 4, so you are never comparing against the last element of inputArray1.

That means that msg is never assigned a new value and remains true.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Wow. Thanks. can you please explain me how "indexOf" works? Also, is it possible to use input textbox instead of hard-coded values? – Vaibhav Shankar Oct 25 '18 at 22:52
  • `indexOf` returns the index of the element in the array. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf for more info. *"Also, is it possible to use input textbox instead of hard-coded values?"* Of course, this is just an example. The function `contains` in my example doesn't care how the array it receives was created. – Felix Kling Oct 25 '18 at 22:55
  • I updated my answer to try to explain why your code doesn't work. – Felix Kling Oct 25 '18 at 23:22
  • Thank you so much. I can understand now. Although using input text box doesnt seem to work. I'm getting an error in button onclick function in html. – Vaibhav Shankar Oct 26 '18 at 04:04
0

check whether the values in sub array consecutively matches the numbers in big array

You can simplify the problem by using Array.join() and String.search():

const arr = [1, 3, 6, 5, 4]

/* test */
console.log(isSubArray(arr, [1,3,6])) // true
console.log(isSubArray(arr, [1,6]))   // false
console.log(isSubArray(arr, [6,5,4])) // true
console.log(isSubArray(arr, [5,4,7])) // false
console.log(isSubArray(arr, [54]))    // false

function isSubArray(original, guess) {
  const a = original.join()
  const b = guess.join()
  return a.search(b) >= 0 
}
jonathangersam
  • 1,137
  • 7
  • 14