【问题标题】:Mathematical Concept In Multi-Dimensional Array Sorting多维数组排序中的数学概念
【发布时间】:2017-06-05 12:28:03
【问题描述】:

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

功能要求

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

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

示例输出:'quick, brown, dog', 'lazy black fox' 等

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

编写代码的人清楚地了解了一些我不了解的概念或公式。只有两个例子,循环内使用的“前一个”变量,以及他们决定增加 j 变量的战略位置。在我看来,他们可能知道一些数学公式。

代码 下面是没有 cmets 的代码。但是,如果您访问此codepen,我已经包含了相同的代码和大量解释程序如何工作的 cmets,因此您不必从头开始跟踪所有内容。您还可以在内置控制台中测试输出。

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']]);

【问题讨论】:

  • 我不知道这里有任何数学“概念”或公式。在任何情况下,解决方案都是不正确的。如果您向主“向量”添加一个额外的“向量”,该函数会计算正确的“组合”数量,但它会写入重复项。看到这个:codepen.io/anon/pen/PjwKNv

标签: javascript arrays algorithm sorting


【解决方案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

【讨论】:

  • 非常感谢您抽出宝贵时间,但我将删除此线程,因为我需要回到绘图板,因为我的解决方案不起作用,并且在这里没有什么用处。我会看看这个。
  • 但是您可以使用给定的方法创建有效的解决方案。够清楚吗?
  • 有点。我不太确定您的代码在这句话下的含义是什么,“您可以通过使用范围为 0..M-1 的计数器进行 for 循环并将每个数字与该计数器分开并获取相应的项目来生成组合。”跨度>
  • 优秀。感谢您的帮助,今晚会受到重创。例如,假设 M 是 12,我们创建一个循环 m 减去 1 次 (11) 的 for 循环?此外,当您设置 t = c 时,它是否也等于 11?不确定 t 代表什么。 @MBo
【解决方案2】:

.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);

【讨论】:

  • 谢谢,我去看看!
猜你喜欢
  • 1970-01-01
  • 2017-01-30
  • 1970-01-01
  • 2020-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多