多维数组排序中的数学概念

时间:2017-06-05 12:28:04

标签: javascript arrays algorithm sorting

我发现这个代码是在线编写的(不是由我编写的),并希望得到一个数学公式或概念的答案,使这个功能起作用。我很好奇这个人是如何设计的。首先,我将解释函数必须产生的要求,然后我将提供代码,以及指向工作代码笔的链接以进一步破解。附:问题使用单词“vector”,但由于这是Javascript,vector只表示数组。

功能要求

给出一个单词向量的向量,例如。 [['quick','lazy'],['brown','black','grey'],['fox','dog']]。

编写一个函数,打印第一个向量中一个单词的所有组合,第二个向量中的一个单词等。 解决方案可能不 使用递归。每个向量中的向量数和元素数可能会有所不同。

示例输出:'快速,棕色,狗','懒惰的黑狐狸'等。

我目前的理解水平 我已经意识到,通过使用乘法原理,找到在这种情况下可用的可能组合的数量是将每个内部向量的长度相互乘以。对于此特定示例,我们总共得到 12 (2x3x2)种不同的可能组合。然而,我脱落的地方是在程序的4个嵌套for循环部分内。

无论谁编写代码,都清楚地理解我不遵守的一些概念或公式。只有两个例子,是循环中使用的“前一个”变量,以及他们决定增加j变量的位置的战略位置。在我看来,他们可能会意识到一些数学公式。

代码 以下是没有评论的代码。但是,如果您转到此codepen,我已经包含了相同的代码,其中包含大量注释,解释了程序的工作原理,因此您无需从头开始跟踪所有内容。您还可以在内置控制台中测试输出。

function comboMaker(vector) {

  var length = vector.length;

  var solutions = 1;
  for (var i = 0; i < length; i++) {
    solutions *= vector[i].length;
  }

  var combinations = [];
  for (var i = 0; i < solutions; i++) {
    combinations[i] = [];
  }

  var previous = 1;

  for (var i = 0; i < length; i++) {

    for (var j = 0; j < solutions;) {

      var wordCount = vector[i].length;
      previous *= vector[i].length;

      for (var l = 0; l < wordCount; l++) {

        for (var k = 0; k < (solutions/previous); k++) {
          combinations[j][i] = vector[i][l];
          j++
        }
      }
    }
  }

  for (var i = 0; i < solutions; i++) {
    console.log(combinations[i].join(" "));
  }
}

comboMaker([['quick', 'lazy'], ['brown', 'black', 'grey'], ['fox', 'dog']]);

2 个答案:

答案 0 :(得分:1)

您可以将项目组合视为mixed radix numeric system中的数字。 每个位置的基数等于相应数组中的项目数(此处为{2,3,2})。组合M的总数是所有基数的乘积。

您可以生成组合

通过在0 ... M-1范围内使用计数器进行for循环,并从该计数器中分离每个数字并获得相应的项目。伪代码

 M = ProductOfLengthsOfArrays
 for c = 0..M-1
     t = c
     combination = {}
     for i = 0..NumOfArrays-1
         d = t %% Array[i].Length   //modulo operation
         t = t / Array[i].Length    //integer division
         combination.add(Array[i][d])
     output combination

通过从0到M-1的混合基数计数

  if item is last in the array, get first item and increment the next array
  else get the next item in the same array

答案 1 :(得分:0)

.reduce().map()的合作使我们能够为这个问题提出一个非常有效的单行答案。

var data   = [['quick', 'lazy'], ['brown', 'black', 'grey'], ['fox', 'dog'],['jumps','runs']],
    result = data.reduce((p,c) => p.reduce((r,fw) => r.concat(c.map(sw => fw + " " + sw)),[]));
console.log(result);