【问题标题】:Algorithm for finding the difference between two arrays查找两个数组之间差异的算法
【发布时间】:2009-02-19 18:23:13
【问题描述】:

给定两个数组,是否有一种快速算法可以找到两个数组中所有不同的元素?例如,考虑两个 Keys 数组(如键盘键)结构。一个代表当前按下的按键,另一个代表上一个时间步按下的按键。

Keys[] oldKeys = LastKeyboardState.GetPressedKeys();
Keys[] currKeys = CurrentKeyboardState.GetPressedKeys();

// the user just pressed these key(s) during the last timestep.
Keys[] diff = ...

非常感谢您的建议!

【问题讨论】:

    标签: arrays c#-2.0


    【解决方案1】:

    好吧,蛮力算法是 m*n,其中 m 和 n 是两个数组的大小。

    如果您使用任何类型的树而不是线性数组,那么您的时间将下降到 m * log2(n)

    算法是

    foreach(key ok in oldkeys)
    {
        if(!oldKeys.Contains(ok))
        {
            diff.add(ok);
        }
    }
    foreach(key nk in newkeys)
    {
        if(!newKeys.Contains(nk))
        {
            diff.add(nk);
        }
    }
    

    【讨论】:

    • 错字:“!oldKeys.Contains(ok)”应该是“!newKeys.Contains(ok)”,反之亦然。
    【解决方案2】:

    试试这个

    var diff = oldKeys.Except(currKeys);
    

    这需要 C# 3.0

    【讨论】:

    • 是否包含不在 oldKeys 中的 currKeys?
    • @devinb,除了会返回 oldKeys,除非它们也出现在 currKeys 中。
    【解决方案3】:

    对 JaredPar 的跟进:这将只显示 oldKeys 中的键,而不显示 currKeys 中的键。所以如果 A 在 currKeys 中但不在 oldKeys 中,它就不会出现在 diff 中。

    var diff = oldKeys.Union(currKeys).Except(currKeys.Intersect(oldKeys))
    

    也会得到这些。

    【讨论】:

      【解决方案4】:

      两个位域,运行二进制 XOR。剩下的 1 就是你想要的。

      【讨论】:

      • 这对数组有什么作用? {A,B} 和 {B,A} 不匹配,不是吗?而且,你的名字真棒。
      • @Gordon:我的回答来自算法 POV。我不确定位域在 C# 中是否有效。但是如果你有字符数组,你总是可以伪造一个。现在,剩下的就是摆弄。我能解释一下吗?
      • @devinb:看看我对 Gordon 的回复。我会使用位域而不是数组来保持状态。而且,谢谢你的赞美:)
      • 在位域中,每个可能的键都有一个位槽 -> A = 位 0,B = 位 1,... Shift = Bit29 或其他。然后它只是对旧字段和新字段进行异或运算。 {A, B} 和 {B, A} 一样是 1100000000...0000。异或它们,你得到 000000000000...0000
      猜你喜欢
      • 2020-01-11
      • 1970-01-01
      • 2018-01-07
      • 2019-01-20
      • 1970-01-01
      • 1970-01-01
      • 2016-07-21
      • 1970-01-01
      • 2015-03-19
      相关资源
      最近更新 更多