Nén hai số nguyên bất chấp trật tự


20

So sánh một cặp theo thứ tự (x, y) với một cặp không có thứ tự {x, y} (bộ), sau đó về mặt lý thuyết, sự khác biệt chỉ là một bit, vì x đến trước hay y yêu cầu chính xác một bit để biểu diễn.

Vì vậy, nếu chúng ta được cung cấp một tập {x, y} trong đó x, y là hai số nguyên 32 bit khác nhau, chúng ta có thể gói chúng thành 63 bit (chứ không phải 64) không? Có thể khôi phục các số nguyên 32 bit ban đầu từ kết quả 63 bit, nhưng không thể khôi phục thứ tự của chúng.

Câu trả lời:


27

Vâng, người ta có thể. Nếu x<y , ánh xạ tập {x,y} thành số

f(x,y)=y(y1)/2+x.

Thật dễ dàng để chỉ ra rằng là tính từ, và vì vậy điều này có thể được giải mã duy nhất. Ngoài ra, khi 0 x < y < 2 32 , chúng ta có 0 f ( x , y ) < 2 63 - 2 31 , do đó, điều này ánh xạ tập { x , y } thành số 63 bit f ( x , y ) . Để giải mã, bạn có thể sử dụng tìm kiếm nhị phân trên y , hoặc tham gia một căn bậc hai: y nên vào khoảng f0x<y<2320f(x,y)<263231{x,y}f(x,y)yy2f(x,y).


1
giống như 1 + 2 + 3 + ... + y + x đẹp!
Troy McClure

1
bất kỳ khái quát cho n ints không có thứ tự? :) về ý nghĩ thứ hai, nhiều hình tứ giác với các dẫn xuất một phần đủ lớn sẽ thực hiện công việc
Troy McClure

4
Một câu trả lời khác có thể hấp dẫn với chi phí tính toán thấp của nó: nếu xykhác nhau, thì hoặc x-y-1hoặc y-x-1(cả mod , tất nhiên) phù hợp với 31 bit. Nếu nhỏ, thì nối và 31 bit cuối cùng của ; mặt khác nối và 31 bit cuối cùng của . Khôi phục hai số bằng cách lấy 32 bit đầu tiên làm một số và thêm 32 bit đầu tiên, 31 bit cuối cùng và hằng số 1 (mod 2 32 ) làm số còn lại. 232x-y-1yx-y-1xy-x-1232
Daniel Wagner

1
phương pháp của bạn cũng tổng quát hóa tốt hơn để thêm nhiều số hơn, vì số đầu tiên là "chỉ có vậy" nên có thể xâu chuỗi
Troy McClure

4
@DW: Bạn có thể vui lòng thêm cách bạn đã đưa ra đại diện này không? Nếu không thì có vẻ như bạn đã kéo nó ra khỏi không khí mỏng.
Mehrdad

9

Như một sự bổ sung cho câu trả lời của DW, lưu ý rằng đây là một trường hợp đặc biệt của hệ thống Số tổ hợp , mà gọn bản đồ một chuỗi giảm nghiêm của số nguyên không âm c k > > c 1 đến kck>>c1

N=i=1k(cii).

Con số này có một cách giải thích đơn giản. Nếu chúng ta sắp xếp các chuỗi này theo từ vựng, thì sẽ đếm số lượng các chuỗi nhỏ hơn.N

Để giải mã, chỉ cần gán giá trị lớn nhất sao cho và giải mã là hậu quả .( c kckN- ( ck(ckk)N (k-1)N(ckk)(k1)


4

Tổng số cặp số không có thứ tự trong một tập hợp là . Tổng số cặp số khác nhau không có thứ tự là . Phải mất bit để biểu diễn một cặp số theo thứ tự và nếu bạn có ít hơn một bit, bạn có thể biểu diễn các phần tử của khoảng trắng lên đến . Số lượng các cặp không nhất thiết không có thứ tự khác biệt nhiều hơn một nửa số lượng các cặp được đặt hàng để bạn không thể tiết kiệm một chút trong biểu diễn; số lượng các cặp khác biệt không có thứ tự là ít hơn một nửa, vì vậy bạn có thể tiết kiệm một chút.N ( N + 1 ) / 2 N ( N - 1 ) / 2 2 log 2 ( N ) = log 2 ( N 2 ) N 2 / 2NN(N+1)/2N(N1)/22log2(N)=log2(N2)N2/2

Đối với sơ đồ thực tế dễ tính toán, với là lũy thừa 2, bạn có thể làm việc trên biểu diễn bitwise. Lấy trong đó là toán tử XOR (độc quyền bitwise hoặc). Cặp có thể được phục hồi từ hoặc . Bây giờ chúng ta sẽ tìm kiếm một mẹo để lưu một bit trong phần thứ hai và đưa ra vai trò đối xứng cho và để thứ tự không thể được phục hồi. Với tính toán cardinality ở trên, chúng ta biết sơ đồ này sẽ không hoạt động trong trường hợp .a = x y { x , y } ( a , x ) ( a , y ) x y x = yNa=xy{x,y}(a,x)(a,y)xyx=y

Nếu thì có một số vị trí bit mà chúng khác nhau. Tôi sẽ viết cho bit thứ của (tức là ) và tương tự cho . Đặt lấy vị trí bit nhỏ nhất trong đó và khác nhau: là nhỏ nhất sao cho . là nhỏ nhất sao cho : chúng ta có thể phục hồi từ . Đặt là hoặcx i i x x = i x i 2 ixyxiixx=ixi2ik x y k i x iy i k i một i = 1 k một b x y k b = Σ i < k x i 2 i + Σ i > k x i 2 i - 1 b =ykxykixiyikiai=1kabxyvới bit thứ bị xóa (tức là hoặc ) - để tạo đối xứng xây dựng, chọn nếu và và chọn nếu và . Sử dụng làm đại diện nhỏ gọn của cặp. Cặp ban đầu có thể được phục hồi bằng cách tính toán bit thứ tự thấp nhất được đặt trong , chèn 0 bit vào vị trí này trong (lấy một trong số hoặc ) và lấy xor của số đó vớikb=i<kxi2i+i>kxi2i1b=i<kyi2i+i>kyi2i1xxk=0yk=1yxk=1yk=0(a,b)abxya (mang lại yếu tố khác của cặp).

Trong biểu diễn này, có thể là bất kỳ số nào khác và có thể là bất kỳ số nào có một nửa phạm vi. Đây là một kiểm tra về sự tỉnh táo: chúng tôi nhận được chính xác số lượng đại diện dự kiến ​​của các cặp không có thứ tự.ab

Trong giả, với ^, &, |, <<, >>, ~là C giống như toán tử Bitwise (xor, and, or, trái ca, ngay ca, bổ sung):

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)

0

Một bằng chứng phi cấu trúc: có không có thứ tự các cặp số nguyên 32 bit khác nhau.(232×232232)/2=231(2321)<263

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.