Il differenza di somme soluzione proposta da Tobi e Mario può infatti essere generalizzato a qualsiasi altro tipo di dati per cui possiamo definire una (costante di tempo) un'operazione binaria ⊕ che è:Θ ( n )⊕
- totale , tale che per tutti i valori e b , un ⊕ b è definito e dello stesso tipo (o almeno di alcune appropriata supertype di esso, per cui l'operatore ⊕ è ancora definita);un'Ba ⊕ b⊕
- associativo , tale che ;a ⊕ ( b ⊕ c ) = ( a ⊕ b ) ⊕ c
- commutativo , tale che ; ea ⊕ b = b ⊕ a
- cancellativo , tale che esiste un operatore inverso che soddisfa ( a ⊕ b ) ⊖ b = a . Tecnicamente, questa operazione inversa non deve necessariamente essere a tempo costante, fintanto che "sottrarre" due somme di n elementi ciascuna non richiede più di O ( n ) tempo.⊖( a ⊕ b ) ⊖ b = anO ( n )
(Se il tipo può assumere solo un numero finito di valori distinti, queste proprietà sono sufficienti per trasformarlo in un gruppo abeliano ; anche se non lo sarà, sarà almeno un semigruppo di annullamento commutativo .)
Usando tale operazione , possiamo definire la "somma" di un array a = ( a 1 , a 2 , ... , a n ) come ( ⊕⊕a = ( a1, a2, ... , unn) Dato un altro array b = ( b 1 , b 2 , … , b n , b n + 1 ) contenente tutti gli elementi di un più un elemento in più x , abbiamo quindi ( ⊕
( ⊕a ) = a1⊕ a2⊕ ⋯ ⊕ an.
b = ( b1, b2, ... , bn, bn + 1)un'X , e così possiamo trovare questo elemento in più calcolando:
x = ( ⊕( ⊕b ) = ( ⊕a ) ⊕ xx = ( ⊕b ) ⊖ ( ⊕a ) .
Ad esempio, se i valori nelle matrici sono numeri interi, l'aggiunta di numeri interi (o l'aggiunta modulare per tipi di numeri interi di lunghezza finita) può essere utilizzata come operatore , con la sottrazione come operazione inversa ⊖ . In alternativa, per qualsiasi tipo di dati i cui valori possono essere rappresentati come stringhe di bit a lunghezza fissa, possiamo usare XOR bit a bit sia come ⊕ che ⊖ .⊕⊖⊕⊖
Più in generale, possiamo persino applicare il metodo XOR bit a bit a stringhe di lunghezza variabile, imbottendole fino alla stessa lunghezza necessaria, purché abbiamo un modo per rimuovere in modo reversibile l'imbottitura alla fine.
In alcuni casi, questo è banale. Ad esempio, le stringhe di byte con terminazione null in stile C codificano implicitamente la loro stessa lunghezza, quindi applicare questo metodo per loro è banale: quando XORing due stringhe, riempire quella più corta con byte null per far corrispondere la loro lunghezza e tagliare eventuali null finali il risultato finale. Tuttavia, le stringhe di somma XOR intermedie possono contenere byte null, quindi dovrai memorizzarne esplicitamente la lunghezza (ma ne avrai bisogno solo uno o due).
1001232byte di lunghezza, potremmo codificare la lunghezza di ogni stringa come numero intero a 32 bit e anteporla alla stringa. Oppure potremmo persino codificare lunghezze di stringa arbitrarie usando un po 'di prefisso e anteporre quelle alle stringhe. Esistono anche altre possibili codifiche.
Θ ( n )
L'unica parte potenzialmente complicata è che, affinché la cancellazione funzioni, dobbiamo scegliere un'unica rappresentazione canonica di bitstring per ciascun valore, che potrebbe essere difficile (anzi, potenzialmente persino indecidibile dal punto di vista computazionale) se i valori di input nei due array possono essere dati in diverse rappresentazioni equivalenti. Questa non è una debolezza specifica di questo metodo, tuttavia; qualsiasi altro metodo per risolvere questo problema può anche fallire se l'input può contenere valori la cui equivalenza è indecidibile.