정렬 된 쌍 (x, y)을 정렬되지 않은 쌍 {x, y} (집합)과 비교하면 이론적으로 정보는 x가 먼저 오거나 y가 정확히 하나의 비트를 나타내는 지 여부에 따라 한 비트에 불과합니다.
따라서 x, y가 두 개의 서로 다른 32 비트 정수인 {x, y} 세트가 주어지면 63 비트 (64가 아닌)로 묶을 수 있습니까? 63 비트 결과에서 원래 32 비트 정수를 복구 할 수 있지만 순서를 복구 할 수는 없습니다.
정렬 된 쌍 (x, y)을 정렬되지 않은 쌍 {x, y} (집합)과 비교하면 이론적으로 정보는 x가 먼저 오거나 y가 정확히 하나의 비트를 나타내는 지 여부에 따라 한 비트에 불과합니다.
따라서 x, y가 두 개의 서로 다른 32 비트 정수인 {x, y} 세트가 주어지면 63 비트 (64가 아닌)로 묶을 수 있습니까? 63 비트 결과에서 원래 32 비트 정수를 복구 할 수 있지만 순서를 복구 할 수는 없습니다.
답변:
네, 할 수 있습니다. 경우 , 설정된 맵핑 개수
가 형용사 임을 쉽게 알 수 있으므로 고유하게 디코딩 할 수 있습니다. 또한 일 때 이 있으므로 세트 \ {x, y \} 를 63 비트 숫자 f (x, y)로 바꿉니다 . 디코딩하려면 y 에서 이진 검색을 사용 하거나 제곱근을 사용할 수 있습니다 . y 는 대략 \ lfloor \ sqrt {2 f (x, y)} \ rfloor 이어야합니다 .
x
하고 y
어느 한 후, 다른 x-y-1
또는 y-x-1
(둘 개조 물론) 31 비트에 들어 맞는다. 경우 작고, 다음 연결할 마지막 31 비트 ; 그렇지 않으면 의 마지막 31 비트와 연결 합니다 . 처음 32 비트를 하나의 숫자로 취하고 첫 32 비트, 마지막 31 비트 및 상수 1 (mod )을 다른 것으로 추가하여 두 숫자를 복구하십시오 . 2 32x-y-1
y
x-y-1
x
y-x-1
집합의 순서가없는 숫자 쌍의 총 수 는 입니다. 고유 한 숫자 의 정렬되지 않은 쌍의 총 수 는 입니다. 순서가 지정된 숫자 쌍을 나타내는 데 비트가 필요하며, 비트가 1 개 미만인 경우 최대 의 공간 요소를 나타낼 수 있습니다 . 정렬되지 않은 불필요하게 구별되는 쌍의 수는 정렬 된 쌍의 수의 절반보다 약간이므로 표현에 비트를 저장할 수 없습니다. 정렬되지 않은 고유 쌍의 수는 절반보다 약간 적으므로 비트를 절약 할 수 있습니다.
은 2의 거듭 제곱 으로 계산하기 쉬운 실용적인 체계의 경우 비트 표현을 할 수 있습니다. 취하십시오 여기서 는 XOR (비트 배타적 또는 연산자) 연산자입니다. 쌍 는 또는 에서 복구 할 수 있습니다 . 이제 두 번째 부분에서 1 비트를 저장하는 트릭을 찾고 와 대칭 역할을 부여 하여 순서를 복구 할 수 없습니다. 위의 카디널리티 계산에서 경우이 체계가 작동하지 않는다는 것을 알고 있습니다.
경우 그 때 다를 일부 비트 위치가있다. I는 쓸 것이다 위한 의 번째 비트 (즉, )와 마찬가지로 대 . 하자 최소 비트 위치 취할 와 상이을 : 가장 작은 되도록 . 는 가장 작은 이므로 : 에서 를 복구 할 수 있습니다 . 를 또는 라고 하자와 소거 된 비트 일 (즉, 또는 선택, 건설 대칭 있도록 -) 경우 및 , 그리고 선택 경우 및 . 사용 한 쌍의 컴팩트 한 표현으로. 원래 쌍은 설정된 최하위 비트를 계산하고 의이 위치에 0 비트를 삽입하고 ( 또는 중 하나를 생성 ) 해당 숫자의 xor를 사용하여 복구 할 수 있습니다. (쌍의 다른 요소를 산출).
이 표현에서 는 0이 아닌 임의의 숫자 일 수 있으며 는 범위가 절반 인 숫자 일 수 있습니다. 이것은 순전 한 점검입니다. 우리는 정렬되지 않은 쌍의 예상 표현 수를 정확하게 얻습니다.
의사 코드와 ^
, &
, |
, <<
, >>
, ~
인 C 형 비트 연산자 (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)
비 건설 증거 : 순서가 없습니다 서로 다른 32 비트 정수 쌍