在PHP中查找Node和Golang这两个数组之间的差异

Finding the difference between two arrays in PHP, Node and Golang

本文关键字:两个 数组 之间 查找 PHP Node Golang      更新时间:2023-11-06

下面是我需要做的一个典型示例

$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(29400140)

将转换为

$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端口。

这里是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/)这将使您的CCD_ 4更小。