亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

以唯一和確定的方式將兩個整數映射為一個

以唯一和確定的方式將兩個整數映射為一個

以唯一和確定的方式將兩個整數映射為一個假設兩個正整數A和B,我想把這兩個正整數組合成一個整數C。不可能有其他的整數D和E組合到C,所以把它們和加法運算符結合起來就不起作用了。例如:30+10=40=40+0=39+1也不起作用?!?1”+“2”=312=“3”+“12”這種組合操作也應該是確定性的(總是用相同的輸入產生相同的結果)。和應該總是在整數的正反兩面產生一個整數。
查看完整描述

3 回答

?
元芳怎么了

TA貢獻1798條經驗 獲得超7個贊

Cantor配對函數考慮到它的簡單、快速和空間效率,它確實是最好的之一,但是在Wolfram上有一些更好的出版。馬修·斯祖德齊克著..Cantor配對函數(相對的)的限制是編碼結果的范圍并不總是停留在2N如果輸入為兩個比特整數N位整數。也就是說,如果我的輸入是兩個16位整數0 to 2^16 -1,然后2^16 * (2^16 -1)輸入的組合是可能的,所以很明顯針孔原理,我們至少需要一個大小的輸出。2^16 * (2^16 -1),等于2^32 - 2^16的地圖32在理想情況下,位數應該是可行的。在編程世界中,這可能并不是沒有實際意義的。


Cantor配對函數:

(a + b) * (a + b + 1) / 2 + a; where a, b >= 0

兩個最大的16位整數(65535,65535)的映射將是8589803520,正如您所看到的,這不能適合32位。

進入Szudzik函數:

a >= b ? a * a + a + b : a + b * b;  where a, b >= 0

現在(65535,65535)的映射將是4294967295,正如您所看到的,這是一個32位(0到2^32-1)整數。這就是這個解決方案理想的地方,它只是利用了空間中的每一個點,所以沒有什么能獲得更高的空間效率。


現在,考慮到我們通常在語言/框架中處理不同大小的數字簽名實現,讓我們考慮signed 16位整數-(2^15) to 2^15 -1(稍后我們將看到如何將輸出擴展到跨越簽名范圍)。自ab必須是積極的,他們的范圍從0 to 2^15 - 1.

Cantor配對函數:

兩個最大16位有符號整數(32767,32767)的映射將是2147418112,這只是缺少有符號32位整數的最大值。

現在Szudzik函數:

(32767,32767)=>1073741823,小得多。

讓我們來解釋一下負整數。這超出了我所知道的最初的問題,但只是為了幫助未來的訪客。

Cantor配對函數:

A = a >= 0 ? 2 * a : -2 * a - 1;
B = b >= 0 ? 2 * b : -2 * b - 1;
(A + B) * (A + B + 1) / 2 + A;

(-32768,-32768)=>8589803520,即64。16位輸入的64位輸出可能是不可原諒的!

Szudzik函數:

A = a >= 0 ? 2 * a : -2 * a - 1;
B = b >= 0 ? 2 * b : -2 * b - 1;
A >= B ? A * A + A + B : A + B * B;

(-32768,-32768)=>4294967295,對于無符號范圍是32位,對于有符號范圍是64位,但是更好。

現在,所有這些都是積極的。在簽名世界里,如果我們能把一半的輸出轉移到負軸,就會節省更多的空間。..你可以這樣為Szudzik:

A = a >= 0 ? 2 * a : -2 * a - 1;
B = b >= 0 ? 2 * b : -2 * b - 1;
C = (A >= B ? A * A + A + B : A + B * B) / 2;
a < 0 && b < 0 || a >= 0 && b >= 0 ? C : -C - 1;

(-32768, 32767) => -2147483648

(32767, -32768) => -2147450880

(0, 0) => 0 

(32767, 32767) => 2147418112

(-32768, -32768) => 2147483647

我所做的:在計算重量之后2對于輸入,并通過函數,然后將輸出除以2,然后將其中的一部分乘成負軸。-1.

有關簽名范圍內的任何輸入,請參見結果。16位數,輸出在有符號的范圍內。32位整數,很酷。我不知道如何對Cantor配對功能進行相同的方式,但沒有嘗試,因為它沒有那么有效。此外,Cantor配對函數所涉及的更多的計算也意味著它的速度也較慢。.

這里是一個C#實現。

public static long PerfectlyHashThem(int a, int b)
{
    var A = (ulong)(a >= 0 ? 2 * (long)a : -2 * (long)a - 1);
    var B = (ulong)(b >= 0 ? 2 * (long)b : -2 * (long)b - 1);
    var C = (long)((A >= B ? A * A + A + B : A + B * B) / 2);
    return a < 0 && b < 0 || a >= 0 && b >= 0 ? C : -C - 1;
}

public static int PerfectlyHashThem(short a, short b)
{
    var A = (uint)(a >= 0 ? 2 * a : -2 * a - 1);
    var B = (uint)(b >= 0 ? 2 * b : -2 * b - 1);
    var C = (int)((A >= B ? A * A + A + B : A + B * B) / 2);
    return a < 0 && b < 0 || a >= 0 && b >= 0 ? C : -C - 1;
}

因為中間計算可以超過2N有符號整數,我使用了4N整數類型(最后一次除以2把結果帶回2N).

我在交替解決方案上提供的鏈接很好地描述了利用空間中的每一個點的函數的圖表。令人驚奇的是,您可以唯一地將一對坐標編碼為單個數字,可以可逆地進行編碼!神奇的數字世界!


查看完整回答
反對 回復 2019-07-06
?
慕少森

TA貢獻2019條經驗 獲得超9個贊

如果A和B可以用2個字節表示,則可以在4個字節上組合它們。把A放在最重要的一半,B放在最不重要的一半。

在C語言中,這給出了(假設size of(Short)=2和size of(Int)=4):

int combine(short A, short B)
{
    return A<<16 | B;
}

short getA(int C)
{
    return C>>16;
}

short getB(int C)
{
    return C & 0xFFFF;
}


查看完整回答
反對 回復 2019-07-06
  • 3 回答
  • 0 關注
  • 1420 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號