views:

1386

answers:

4

Given two arrays, is there a fast algorithm for finding all elements in the two that are different? For example, consider two arrays of Keys (as in keyboard keys) structs. One represents the currently depressed keys, and the other represents the keys depressed in the last timestep.

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

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

Suggestions are much appreciated!

+5  A: 

Try this

var diff = oldKeys.Except(currKeys);

This requires C# 3.0

JaredPar
Does Except include the currKeys that are not in oldKeys?
@devinb, Except will return oldKeys except where they also appear in currKeys.
JaredPar
+1  A: 

Two bitfields, run binary XOR. Whatever 1s you are left with is what you want.

dirkgently
How would that work for arrays? {A,B} and {B,A} wouldn't match, would they? And, your name is AWESOME.
Do you have some sample code for this?
Gordon Carpenter-Thompson
@Gordon: my answer was from an algorithmic POV. I am not sure bitfields work in C#. But if you have character arrays, you could always fake one. Now, all you are left with is bit fiddling. Am I able to explain?
dirkgently
@devinb: Look at my reply to Gordon. I would use bitfields instead of arrays to keep state. And, thanks for the compliment :)
dirkgently
In a bitfield, you'd have a bit slot for every possible key -> A = bit 0, B = bit 1, ... Shift = Bit29 or whatever. Then it's just XORing the old and the new fields. {A, B} would be 1100000000...0000as would {B, A}. XOR them and you get 000000000000...0000
Eclipse
+2  A: 

To followup on JaredPar: that will only show the keys in oldKeys but not in currKeys. So if A is in currKeys but not in oldKeys, it will not appear in diff.

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

Will get those as well.

Tom Ritter
+4  A: 

Well, brute force algorithm would be m*n where m and n are the sizes of your two arrays.

If you're using any sort of a tree instead of a linear array, then your time falls to m * log2(n)

The algorithm for that is

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