O diferença-de-somas solução proposta por Tobi e Mario pode na verdade ser generalizada para qualquer outro tipo de dados para os quais podemos definir um (constante de tempo) operação binária ⊕ que é:Θ ( n )⊕
- total , de modo que, para quaisquer valores e b , a ⊕ b seja definido e do mesmo tipo (ou pelo menos de algum supertipo apropriado, para o qual o operador ⊕ ainda esteja definido);umaba ⊕ b⊕
- associativo , de modo que ;a ⊕ ( b ⊕ c ) = ( a ⊕ b ) ⊕ c
- comutativo , tal que ; ea ⊕ b = b ⊕ a
- cancelável , de modo que exista um operador inverso que satisfaça ( a ⊕ b ) ⊖ b = a . Tecnicamente, essa operação inversa nem precisa necessariamente ser de tempo constante, desde que "subtraindo" duas somas de n elementos cada uma não demore mais que O ( n ) tempo.⊖( a ⊕ b ) ⊖ b = anO ( n )
(Se o tipo só pode receber um número finito de valores distintos, essas propriedades são suficientes para transformá-lo em um grupo abeliano ; mesmo se não, será pelo menos um semigrupo comutativo de cancelamento .)
Usando essa operação , podemos definir a "soma" de uma matriz a = ( a 1 , a 2 , … , a n ) como ( ⊕⊕a = ( a1, um2, … , Umn) Dada outra matriz b = ( b 1 , b 2 , … , b n , b n + 1 ) contendo todos os elementos de a mais um elemento extra x , temos, portanto, ( ⊕
( ⊕a ) = a1⊕ a2⊕ ⋯ ⊕ umn.
b = ( b1, b2, … , Bn, bn + 1)umax , e assim podemos encontrar esse elemento extra computando:
x = ( ⊕( ⊕b ) = ( ⊕a ) ⊕ xx = ( ⊕b ) ⊖ ( ⊕um ) .
Por exemplo, se os valores nas matrizes são números inteiros, em seguida, adição inteiro (ou adição modular para tipos inteiros finito de comprimento) pode ser usado como o operador , com subtracção como a operação inversa ⊖ . Como alternativa, para qualquer tipo de dados cujos valores possam ser representados como cadeias de bits de comprimento fixo, podemos usar o XOR bit a bit como ⊕ e ⊖ .⊕⊖⊕⊖
De maneira mais geral, podemos aplicar o método XOR bit a bit em seqüências de comprimento variável, preenchendo-as com o mesmo comprimento necessário, desde que tenhamos alguma maneira de remover reversivelmente o preenchimento no final.
Em alguns casos, isso é trivial. Por exemplo, cadeias de bytes terminadas nulas no estilo C codificam implicitamente seu próprio comprimento, portanto, aplicar esse método a elas é trivial: ao XORing duas cadeias, preencha a mais curta com bytes nulos para fazer com que seu comprimento corresponda e apare quaisquer nulos à direita extra de o resultado final. Observe que as cadeias intermediárias de soma XOR podem conter bytes nulos; portanto, você precisará armazenar explicitamente seu comprimento (mas precisará apenas de um ou dois deles no máximo).
10 00 01232.bytes, poderíamos codificar o comprimento de cada string como um número inteiro de 32 bits e anexá-lo à string. Ou podemos até codificar comprimentos arbitrários de cadeias usando algum código de prefixo e anexá-los às cadeias. Também existem outras codificações possíveis.
Θ ( n )
A única parte potencialmente complicada é que, para que o cancelamento funcione, precisamos escolher uma representação de cadeia de bits canônica exclusiva para cada valor, o que pode ser difícil (de fato, potencialmente até indecidível computacionalmente) se os valores de entrada nas duas matrizes puderem ser dados em diferentes representações equivalentes. Esta não é uma fraqueza específica deste método, no entanto; qualquer outro método para resolver esse problema também poderá falhar se for permitido que a entrada contenha valores cuja equivalência seja indecidível.