【问题标题】:Sort an array of arrays by elements contained in each array按每个数组中包含的元素对数组数组进行排序
【发布时间】:2023-03-22 01:07:01
【问题描述】:

我需要遍历图中所有连接的组件。 图的路径存储在数组中,如下所示:

var paths = [
  [5,6],
  [1,2],
  [4,7,5,6],
  [6]
]

在这里我看到paths[2]=[4,7,5,6] 依赖于paths[0]=[5,6],而paths[0]=[5,6] 又依赖于paths[3]=[6]。

现在,我需要递归遍历所有路径以检查哪个路径包含在另一个路径中,并首先处理可以帮助解决另一个路径的路径,即我需要检查哪些数组包含在其他一些数组中:

示例:

process [6]
process [5,6]
process [4,7,5,6]
process [1,2]

由于元素数量众多,我宁愿不使用递归。 有没有办法通过包含在每个其他数组中的一个数组中的元素对这个数组列表进行排序,以便我可以通过迭代来处理它们?

编辑: 我认为这可以通过为每个路径分配权重来解决,如下所示: 每个路径中包含的节点的总和乘以该节点在其他路径中包含的次数,然后按长度升序和权重降序对路径进行排序 - 但这只是我的猜测......

【问题讨论】:

  • Due to the large amount of elements, i would prefer not to use recursion. 如果你担心一个函数会达到最大堆栈大小,有办法解决这个问题。这有点像“滚动您自己的 TCO”,但它可能非常有效here is a good article。无论如何,我认为[5, 6] 包含[6] 是否正确,因为后者更小?本质上,只有较大的数组才会包含较小的数组,[5, 6] 不会包含 part of [4, 7, 5, 6],对吗?
  • @Vld:我昨天刚读到你提到的那篇文章,我必须承认我还在消化它的路上......重点是:它们也可以有相同的长度,按排序长度是我的第一次尝试,遗憾的是在一些更复杂的图表中没有成功..
  • 在您的情况下,配对智能比较不起作用吗?如果n 是路径数,则需要O(n*n) 时间(假设路径长度小于某个最大长度k)
  • @deblocker 是的,我也花了一些时间来处理那篇文章,但我发现这些技术很有趣。有点烦人的是,您确实必须修改您的算法才能使用它们,但这比炸毁堆栈要好。无论如何,简单的按长度排序不会太难arr.sort((a, b) => a.length - b.length)) 会按长度排序包含数组的数组example。它只是一个级别,但深入许多级别将是遍历所有内容并基本上对遇到的任何数组进行排序的问题。
  • @RishitSanmukhani:您能详细说明一下吗?我不确定成对比较是否对我有帮助。

标签: javascript arrays algorithm geometry


【解决方案1】:

我猜......如果我理解正确,你是在依赖排序之后。那么我相信完成这项工作的一种可能方法如下。这是我可以想出的一种方法,但也可能有更简单的解决方案。

我们必须将相互依赖的连续项组成一组(例如[6]、[5,6]和[4,7,5,6]),然后根据它们的依赖关系对它们进行排序。我想在不同的组之间进行排序是没有必要的,因为它们的项目不相关(即[1,2] 可以在带有[6]、[5,6] 和[4,7,5,6] 的排序组之前或之后)。

var paths = [
             [5,6],
             [1,2],
             [4,7,5,6],
             [6]
            ],
      lut = paths.reduce((table,path,i) => (path.forEach(n => table[n] = table[n] ? table[n].concat([[i,path.length]])
                                                                                            .sort((a,b) => a[1]-b[1])
                                                                                  : [[i,path.length]]),
                                            table),{}),
   sorted = Object.keys(lut).sort((a,b) => lut[b].length - lut[a].length)
                            .reduce((si,k) => (lut[k].forEach(e => !si.includes(e[0]) && si.push(e[0])),si) ,[])
                            .map(idx => paths[idx]);
console.log(sorted);

好的,我们首先从一个类似对象 (lut) 的查找表中查找,在这种特殊情况下,它的形式类似于

{ '1': [ [ 1, 2 ] ],
  '2': [ [ 1, 2 ] ],
  '4': [ [ 2, 4 ] ],
  '5': [ [ 0, 2 ], [ 2, 4 ] ],
  '6': [ [ 3, 1 ], [ 0, 2 ], [ 2, 4 ] ],
  '7': [ [ 2, 4 ] ] 
}

所以我们现在知道路径 6 的依赖程度最高。 '6': [ [ 3, 1 ], [ 0, 2 ], [ 2, 4 ] ], 表示paths[3] 是单独的;在paths[0],它有一个受抚养人,在paths[2],它有3个受抚养人。所以我们根据家属人数(.sort((a,b) => a[1]-b[1]))进行了排序。 一旦我们有了我们的表,它只会让它们被安排为我们提供所需的索引映射。 .reduce((si,k) => (lut[k].forEach(e => !si.includes(e[0]) && si.push(e[0])),si) ,[]) 行有点搞笑。它所做的是将它的索引推入数组“如果”它不在数组中的每条路径。所以我们从最依赖的一个 (6) 开始,然后我们推送 3、0 和 2。所以当轮到 5 时,我们不会再次推送相同的索引。

【讨论】:

  • 是的!在我看来,您知道问题所在,这是真的吗?如果您能分享更多关于这个论点的知识,对我来说将非常有用。你是怎么想出“7”:4的?这是我无法意识到的关键点,即使在您过于高级的代码的帮助下。
  • @deblocker 昨天我发布了这个 sn-p 后,我意识到存在一些缺陷,并正在考虑纠正它。今天晚些时候我会尝试发布一些更有效的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-16
相关资源
最近更新 更多