【问题标题】:Finding the difference between two arrays in PHP, Node and Golang在 PHP、Node 和 Golang 中查找两个数组之间的差异
【发布时间】:2015-02-13 09:11:04
【问题描述】:

这是我需要做的一个典型例子

$testArr = array(2.05080E6,29400,420);

$stockArrays =  array(
                      array(2.05080E6,29400,0),
                      array(2.05080E6,9800,420),
                      array(1.715E6,24500,280),
                      array(2.05080E6,29400,140),
                      array(2.05080E6,4900,7));

我需要找出差异最小的 stockArray。一些澄清

  • 保证每个位置的数组元素的数值不重叠。 (即 arr[0] 将始终具有最大值,arr1 将至少小 10 个数量级等)。
  • 在确定最小差异时,差异的绝对值不计算在内。只有不同数组索引的数量很重要。
  • 位置差异确实具有权重。因此,在我的示例中,stockArr1 “更加不同” 也认为它 - 就像它的 stockArr[0] 和 stockArr[3] 对应物一样 - 仅在一个索引位置不同,因为该索引位置更大。
  • stockArrays 元素的数量通常少于 10 个,但可能会更多(尽管从未达到 3 个数字)
  • 库存数组将始终具有相同数量的元素。测试数组将具有相同或更少的元素。但是,当填充较少的 testArr 时,可能匹配的元素始终与 stockArray 位于同一位置。例如

    $testArray(29400,140)

将被转换为

$testArray(0,29400,140);

在进行差异测试之前。

  • 最后,平局是可能的。例如,我上面的匹配示例是 stockArrays[0] 和 stockArrays[3]。

在我的示例中,结果将是

$result = array(0=>array(0,0,1),3=>array(0,0,1));

表示差异最小的股票数组位于索引 0 和 3,差异位于位置 2。

在 PHP 中,我会以 array_diff 为起点来处理所有这些问题。对于 Node/JavaScript,我可能会倾向于使用 php.js array_diff 端口,尽管我倾向于稍微探索一下,因为在最坏的情况下,这是一个 O(n2) 事件。

我是 Golang 的新手,所以我不确定如何在那里实现这个问题。我注意到 Node 确实有一个 array_diff npm 模块。

我有一个不寻常的想法是将数组转换为填充字符串(较小的数组元素填充为 0)并有效地对每个字符的序数值进行 XOR,但认为这可能是一件相当疯狂的事情做。

我关心的是速度,但不是不惜一切代价。在理想情况下,每种目标语言都会使用相同的解决方案(算法),但实际上它们之间的差异可能意味着这是不可能的/不是一个好主意。

也许这里的某个人可能会向我指出实现这一点的不那么繁琐的方式 - 即不仅仅是 array_diff 端口。

【问题讨论】:

  • 致我的反对者——你愿意发表评论吗?您是否觉得问题不清楚,您是否发现我没有对问题进行足够的研究,您是否认为该问题不适合这个论坛......?在没有解释的情况下投反对票有什么用?
  • 我没有投反对票,但你的问题令人困惑,没有多大意义。
  • @OneOfOne - 正如您所看到的,这个问题对正确的读者来说非常有意义。我不想刻薄,但是那些不加解释就拒绝投票的人(对你来说没有)不会进入我的圣诞贺卡清单。

标签: javascript php arrays node.js go


【解决方案1】:

下面是等价的array_diff解决方案:(假设我没弄错)

package main

import "fmt"

func FindLeastDifferent(needle []float64, haystack [][]float64) int {
    if len(haystack) == 0 {
        return -1
    }
    var currentIndex, currentDiff int
    for i, arr := range haystack {
        diff := 0
        for j := range needle {
            if arr[j] != needle[j] {
                diff++
            }
        }
        if i == 0 || diff < currentDiff {
            currentDiff = diff
            currentIndex = i
        }
    }

    return currentIndex
}

func main() {
    idx := FindLeastDifferent(
        []float64{2.05080E6, 29400, 420},
        [][]float64{
            {2.05080E6, 29400, 0},
            {2.05080E6, 9800, 420},
            {1.715E6, 24500, 280},
            {2.05080E6, 29400, 140},
            {2.05080E6, 4900, 7},
            {2.05080E6, 29400, 420},
        },
    )
    fmt.Println(idx)
}

就像你说的 O(n * m) 其中n 是针数组中的元素数,m 是大海捞针中的数组数。

如果您不提前了解大海捞针,那么您可能无能为力来改进这一点。但是,如果您将此列表存储在数据库中,我认为您对字符串搜索的直觉有一定的潜力。例如 PostgreSQL 支持字符串相似度索引。 (这里是对正则表达式类似想法的解释:http://swtch.com/~rsc/regexp/regexp4.html

另一个想法:如果您的数组非常大,您可以计算模糊哈希 (http://ssdeep.sourceforge.net/),这将使您的 n 更小。

【讨论】:

  • 感谢您提供非常有用的答案。我将这个问题保持一段时间,看看我是否得到任何其他有用的反馈。再次感谢。
猜你喜欢
  • 2020-01-11
  • 1970-01-01
  • 2018-01-07
  • 2014-08-05
  • 1970-01-01
  • 2019-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多