Il numero totale di coppie di numeri non ordinate in un set di è N ( N + 1 ) / 2 . Il numero totale di coppie non ordinate di numeri distinti è N ( N - 1 ) / 2 . Richiede 2 log 2 ( N ) = log 2NN(N+1)/2N(N−1)/2 bit per rappresentare una coppia ordinata di numeri, e se si ha uno meno bit, si può rappresentare elementi di uno spazio di fino a N 2 / 22log2(N)=log2(N2)N2/2. Il numero di coppie non ordinate non necessariamente distinte è leggermente più della metà del numero di coppie ordinate, quindi non è possibile salvare un po 'nella rappresentazione; il numero di coppie distinte non ordinate è leggermente inferiore alla metà, quindi puoi risparmiare un po '.
Per uno schema pratico che è facile da calcolare, con è una potenza di 2, puoi lavorare sulla rappresentazione bit a bit. Prendi a = x ⊕ y dove ⊕ è l'operatore XOR (bit a bit esclusivo o). La coppia { x , y } può essere recuperata da ( a , x ) o ( a , y ) . Ora cercheremo un trucco per risparmiare un po 'nella seconda parte, e dare un ruolo simmetrica per x e yNa=x⊕y⊕{x,y}(a,x)(a,y)xyin modo che l'ordine non possa essere recuperato. Dato il calcolo della cardinalità sopra, sappiamo che questo schema non funzionerà nel caso in cui .x=y
Se allora c'è qualche posizione in cui differiscono. Scriverò x i per l' i esimo bit di x (cioè x = ∑ i x i 2 i ), e allo stesso modo per y . Lasciare k prendere la posizione più piccolo pezzo in cui x ed y differiscono: k è il più piccolo i tale che x i ≠ y i . k è il più piccolo i tale che un i =x≠yxiixx=∑ixi2iykxykixi≠yiki : possiamo recuperare k da a . Let bai=1kab o o y con il k bit bit cancellato (ovvero b = ∑ i < k x i 2 i + ∑ i > k x i 2 i - 1 oppure b = ∑ i < k y i 2 i + ∑ i > k y i 2 i -xykb=∑i<kxi2i+∑i>kxi2i−1 ) - per rendere simmetrica la costruzione, selezionarexse x k =0e y k =1, quindi selezionareyse x k =1e y k =0. Utilizzare(a,b)come rappresentazione compatta della coppia. La coppia originale può essere recuperata calcolando il bit di ordine più basso impostato ina, inserendo uno 0 bit in questa posizione inb(ottenendo uno dixoy) e prendendo il xor di quel numero conb=∑i<kyi2i+∑i>kyi2i−1xxk=0yk=1yxk=1yk=0(a,b)abxya
ab
In pseudocodice, con ^
, &
, |
, <<
, >>
, ~
essendo C-like operatori bit (XOR, e, o, sinistra-shift, shift destro, complemento):
encode(x, y) =
let a = x ^ y
let k = lowest_set_bit_position(a)
let low_mask = (1 << k) - 1
let z = if x & (1 << k) = 0 then x else y
return (a, (z & low_mask) | (z & ~low_mask) >> 1)
decode(a, b) =
let k = lowest_set_bit_position(a)
let low_mask = (1 << k) - 1
let x = (b & low_mask) | ((b & ~low_mask) << 1)
return (x, a ^ x)