如何检查较大的数组是否包含某个较小的数组?

时间:2019-01-12 00:04:05

标签: javascript

对于家庭作业,我需要编写一个程序,该程序接受两个参数,它们是自然数数组,并带有警卫(0)。

程序应检查第二个数组中包含的元素序列(不包含0)是否完全出现在第一个数组中的任何位置。如果是这样,则程序将返回第一个数组用来开始包含在第二个数组中的元素序列的元素的索引。如果没有这样的序列,则程序返回grep "two" testfile | sed -n 2p prints "twochicken" grep "two" testfile | sed -n 1p prints "twofish" 。如果存在多个此类序列,则应返回找到的第一个序列的索引(具有最小索引的序列)。

示例:

-1

现在,我已经编写了部分起作用的代码,但似乎没有通过所有测试。

-> find([2, 4, 6, 8, 10, 12, 0], [6, 8, 0])

-> 2

-> find([2, 4, 6, 8, 10, 12, 0], [10, 12, 14, 0])

-> -1

基本上我不知道中断是否是在此处添加的正确内容,因为我不确定它在JavaScript中的工作方式(循环中断)。

3 个答案:

答案 0 :(得分:1)

您可以使用带有临时索引的嵌套循环。

function find(source, needle) {
  for (var i = 0; source[i] != 0; i++) {
    var k = i;
    var j = 0;
    while (source[k] != 0 && needle[j] != 0) {
      if (source[k++] != needle[j++]) {
        break; // mismatch between source and needle 
      }
    }
    if (needle[j] == 0) {
      return i; // full match with entire needle
    }
  }
  return -1;
}

var res = find([ 1, 7, 8, 2, 3, 4, 5, 0], [2, 3, 4, 0]);
console.log(res);

答案 1 :(得分:0)

我还建议您稍微修改一下方法...目前,您正在对照整个集合检查子集,这与您想要的相反。您想遍历整个集合,对照您的第一个子集值检查给定的集合值,然后遍历以检查其余值是否匹配。这是我建议的方法:

var fullSet = [1, 6, 37, 54, 3, 87, 37, 15, 9, 21, 53];
var subSet1 = [37, 15, 9];
var subSet2 = [37, 54, 3];
var subSet3 = [3, 90, 512];

function find(full, sub) {
  //Loop entire fullset
  for(var i = 0; i < full.length; i++) {
    //Current fullset value and first subset value match
    if(full[i] == sub[0]) {
      var matches = true; //Toggle for if entire subset does not match
      //Loop through subset
      for(var j = 0; j < sub.length; j++) {
        //Check current full set value against subset value
      	if(full[i + j] != sub[j]) {
          matches = false;
          break;
        } 
      }
      //It managed to last the entire subset without finding a mismatch
      //We can thus safely return the current fullset index
      if(matches) {
        return i;
      }
    }
  }
  //Return -1 if no matches found
  return -1;
}

console.log(find(fullSet, subSet1));
console.log(find(fullSet, subSet2));
console.log(find(fullSet, subSet3));

答案 2 :(得分:0)

break in JavaScript

  

终止当前循环,开关或标签语句,并将程序控制权转移到终止语句之后的语句。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/break

现在,您要做的是,对于第一个数组中的每个位置,检查第二个数组是否从该位置开始(并且已完全包含)。如果是,瞧!您可以返回该索引作为结果,因为它是包含数组的最小索引(如果不是最小索引,那么您以前会发现它)。

function find(tab1, tab2) {
  for(var i = 0; tab1[i] != 0; i++) {
    if( canIFindSecondArrayStartingAtPosition(tab1, tab2, i) ) {
      return i;
    }
  }

  // if you haven't returned yet it means that tab2 was not found!
  return -1;
}

现在,如何实现功能canIFindSecondArrayStartingAtPosition

您要访问第二个数组上的每个位置,并检查此位置上的数字是否是相同位置的第一个数组中的数字+初始索引。如果否,则找不到第二个数组,您可以立即返回false。

最后,如果您能够遍历所有第二个数组(并找到所有数字),则返回true。

尝试在不查看我的代码的情况下实现它:

  

因此整个解决方案看起来像。  

function canIFindSecondArrayStartingAtPosition(tab1, tab2, initialPosition) {
    for(var i=0; tab2[i]!=0; i++) {
      if( tab2[i] != tab1[i + initialPosition] ) {
        return false;
      }
    }

    return true;
}

function find(tab1, tab2) {
  for(var i = 0; tab1[i] != 0; i++) {
    if( canIFindSecondArrayStartingAtPosition(tab1, tab2, i) ) {
      return i;
    }
  }

  // if you haven't returned yet it means that tab2 was not found!
  return -1;
}

var res = find([ 1, 7, 8, 2, 3, 4, 5, 0], [2, 3, 4, 0]);
console.log(res);

res = find([2, 4, 6, 8, 10, 12, 0], [10, 12, 14, 0]);
console.log(res);