p進製數k可表示為
k = a0*p^0 + a1*p^1 + a2*p^2 + ... + an*p^n (其中0 <= ai <= p-1),
它可以表示任何乙個自然數。
一種特殊的變進製數,它能夠被用來實現 全排列的hash函式,並且該hash函式能夠實現完美的防碰撞和空間利用(不會發生碰撞,且所有空間被完全使用,不多不少)。
我們考查這樣一種變進製數:第1位逢2進1,第2位逢3進1,……,第n位逢n+1進1。它的表示形式為
k = a1*1! + a2*2! + a3*3! + ... + an*n! (其中
0 <= ai <= i
),也可以擴充套件為如下形式(因為按定義a0始終為0),以與p進製表示相對應:
k = a0*0! + a1*1! + a2*2! + a3*3! + ... + an*n! (其中
0 <= ai <= i
)。(後面的變進製數均指這種變進製數,且採用前一種表示法)
先讓我們來考查一下該變進製數的進製是否正確。假設變進製數k的第i位ai為i+1,需要進製,而ai*i!=(i+1)*i!=1*(i+1)!,即正確的向高位進1。這說明該變進製數能夠正確進製,從而是一種合法的計數方式。
假設我們有b0,b1,b2,b3,...,bn共n+1個不同的元素,並假設各元素之間有一種次序關係 b0
m = d1*1! + d2*2! + ... + dn*n!
因此,每個排列都可以按這種方式表示成乙個n位變進製數。下面,我們來考查n位變進製數能否與n+1個元素的全排列建立起一一對應的關係。
自己的理解
排列p = p1p2p3p4p5..pn
計算每一位的逆序數a:a1a2a3a4..an
然後用逆序數*在第幾位的階乘。
例如:排列: 231654
逆序數:0,0,2,0,1,2
hash值:0*0! + 0*1! + 2*2! + 0*3! + 1*4! + 2*5!
fac陣列為階乘
int fac = ;
int calhash(string aim)
}res += seed * fac[i];
}return res;
}
hash 全排列hash(康托擴充套件)
這裡的雜湊函式是用能對許多全排列問題適用的方法。取n 為基數,狀態第n位的逆序值為雜湊值第n位數。對於空格,取其 9 位置 再乘以8 例如,1 3 7 2 4 6 8 5 8 的雜湊值等於 0 0 0 1 0 2 2 3 1 4 1 5 0 6 3 7 9 8 8 55596 9 具體的原因可以去查...
演算法 全排列
從n個不同元素中任取m m n 個元素,按照一定的順序排列起來,叫做從n個不同元素中取出m個元素的乙個排列。當m n時所有的排列情況叫全排列。用演算法分別實現全排列,其中n個元素儲存在乙個長度為n的陣列中。實現全排列之前,先看一下對進行全排列的一種方法 從圖中可以看出,我們首先從n個元素中取出乙個元...
全排列演算法
1.遞迴全排列 分別將每個位置交換到最前面位,之後全排列剩下的位。遞迴全排列 1 2 3 4 5 1,for迴圈將每個位置的資料交換到第一位 swap 1,1 5 2,按相同的方式全排列剩餘的位 2.字典序全排列演算法 對給定的字符集中的字元規定了乙個先後關係,在此基礎上規定兩個全排列的先後是從左到...