Общее количество неупорядоченных пар чисел в наборе из равно . Общее количество неупорядоченных пар различных чисел равно . Для представления упорядоченной пары чисел требуется битов, и, если у вас на один бит меньше, вы можете представить элементы пространства до . Количество неупорядоченных не обязательно различимых пар немного больше половины количества упорядоченных пар, поэтому вы не можете сохранить бит в представлении; количество неупорядоченных пар немного меньше половины, поэтому вы можете немного сэкономить.N ( N + 1 ) / 2 N ( N - 1 ) / 2 2 лог 2 ( Н ) = войти 2 ( N 2 ) N 2 / 2NN(N+1)/2N(N−1)/22log2(N)=log2(N2)N2/2
Для практической схемы, которую легко вычислить, так как является степенью 2, вы можете работать с побитовым представлением. Возьмем где - оператор XOR (побитовый исключающий или). Пара может быть восстановлена из или . Теперь мы будем искать хитрость для сохранения одного бита во второй части и придания симметричной роли и чтобы порядок не мог быть восстановлен. Учитывая приведенное выше вычисление мощности, мы знаем, что эта схема не будет работать в случае, когда .a = x ⊕ y ⊕ { x , y } ( a , x ) ( a , y ) x y x = yNa=x⊕y⊕{x,y}(a,x)(a,y)xyx=y
Если то есть битовая позиция, в которой они отличаются. Я напишу для го бита (то есть ), а также для . Пусть займет позицию наименьшего бита, где и различаются: - наименьшее такое что . является наименьшим таким, что : мы можем восстановить из . Пусть будет либо либоx≠yxiixx=∑ixi2iykxykixi≠yikiai=1kabxyсо стертым битом (т. е. или ) - чтобы сделать конструкцию симметричной, выберите если и , и выберите если и . Используйте в качестве компактного представления пары. Исходная пара может быть восстановлена путем вычисления бита самого младшего порядка, который установлен в , вставки 0 битов в этой позиции в (с получением одного из или ) и взятия xor этого числа с помощьюkb=∑i<kxi2i+∑i>kxi2i−1b=∑i<kyi2i+∑i>kyi2i−1xxk=0yk=1yxk=1yk=0(a,b)abxya(получая другой элемент пары).
В этом представлении может быть любым ненулевым числом, а может быть любым числом с половиной диапазона. Это проверка работоспособности: мы получаем именно ожидаемое количество представлений неупорядоченных пар.ab
В псевдокоде, с ^
, &
, |
, <<
, >>
, представляют ~
собой С-подобных операторов поразрядными (XOR, и, или, сдвига влево, сдвига вправо, дополнение):
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)