For the full permutation problem, for example, for a set {a,b,c,d,e,f,g}, all possible permutations are {a,b,c,d,e,f,g},{a,b,c,d,e,g,f},{a,b,c,d,f,e,g},...., {G,f,e,d,c,b,a }
Well, if you're going to write a hash-map relationship table to implement the possible mappings for each permutation, then you need to design a hash function (with what as key, how to minimize wasted space ...). is a problem that needs to be considered well).
Interestingly, for such an all- permutation problem, the Cantor expansion method brings an almost perfect function mapping relationship (one by one mapping && double-shot) representation of the model, as follows:
x=a[n]* (n-1)!+a[n-1]* (n-2)!+...+a[i]* (i-1)!+...+a[1]*0!
Where A[i] is an integer, and 0<=a[i]<i,1<=i<=n.
?
The following is a chestnut to explain carefully.
First there is a standard primitive set, where each element has been sequenced according to the agreed size comparison, for example {a,b,c,d,e,f,g}
Now there is a set {a, b,f,e,d,g,c}, which needs to figure out its corresponding key value X, the steps are as follows: ( initial X = 0)
(1) for a, there are 0 less than ain the unlabeled set {b,f,e,d,g,c} except a , so there is x + = 0*6! , and then set a as marked ;
(2) for B, there are 0 less than B in the unlabeled set {f,e,d,g,c} except B, so there is x + = 0*5! , and then set B as marked;
(3) For F, there are 3 less than F in the unlabeled set {e,d,g,c} except F, so there is x + = 3*4! , and then set F as marked;
(4) For E, there are 2 less than E in the unlabeled set {d,g,c} except E, so there is x + = 2*3! , and then set e as marked;
(5) For D, there are 1 less than D in the unlabeled set {g,c} except D, so there is x + = 1*2! , then set D as marked;
(6) For G, there are 1 less than g in the unlabeled set {C} except G, so there is x + = 1*1! , and then set G as marked;
(7) For C, there are 0 less than C in the unlabeled set {} except C, so there is x + = 0*0! , and then set C as marked;
(8) unlabeled set is empty, x =?0*6! +?0*5! +?3*4! +?2*3! +?1*2! +?1*1! +?0*0! = 87, the corresponding key for the collection sequence {a,b,f,e,d,g,c} is 87.
[can be sensitive to the hierarchical role of factorial, as if a two-bit encoding, 10 bits isolated from the bit, the unlabeled set has k elements corresponding to the factorial of k! (0*k! ~ k*k!), which is obviously the next k-1 and (k-1)! "(0*)! ~ (k-1) * (K-1)! Isolated, isolating to ensure that each state is unique.]
?
Note that the full-array hash map here is double-shot, so there is only one key for a particular sequence, so the only key can be reversed to get the unique sequence case, here is the inverse example:
The original set {a,b,c,d,e,f,g} and key = 87 are known, and each factorial factor is calculated individually:
(1) 87/6! = 0 ... for the current unlabeled collection {a,b,c,d,e,f,g}, there are 0 elements of an element smaller than itself is a, so the target sequence set {A}, a is set to marked;
(2) /5! = 0 ... 87. For the currently unlabeled collection {B,c,d,e,f,g}, there are 0 elements that are smaller than themselves, so the target sequence set {A A, b}, set to marked;
(3) 87/4! = 3 ... 15. For the currently unlabeled collection {C,d,e,f,g}, there are 3 elements that are smaller than themselves, so the target sequence set {a,b,f}, F is set to marked;
(4) 15/3! = 2 ... 3. For the currently unlabeled collection {C,d,e,g}, there are 2 elements that are smaller than themselves, so the target sequence set {A,b,f,e}, E is set to marked;
(5) 3/2! = 1 ... 1. For the currently unlabeled collection {C,d,g}, there are 1 elements that are smaller than themselves, so the target sequence set {a,b,f,e,d}, D is set to marked;
(6) 1/1! = 1 ... 0. For the currently unlabeled collection {C,g}, there are 1 elements that are smaller than themselves, so the target sequence set {A,b,f,e,d,g}, G is set to marked;
(7) 0/0! = 0 ... 0. For the currently unlabeled collection {C}, there are 0 elements that are smaller than themselves, so the target sequence set {A,b,f,e,d,g,c}, C is set to marked;
(8) The unlabeled set is empty and ends, and the target sequence {a,b,f,e,d,g,c} corresponding to Key = 87 is obtained.
What do you know about expressions? X =?0*6! +?0*5! +?3*4! +?2*3! +?1*2! +?1*1! +?0*0! = 87 with? {a,b,f,e,d,g,c} corresponds to one by one of each other
?
To summarize:
Always start with a higher-order factorial (example: 6!). 5! ->...->0!), in order to achieve an "isolation" condition, because the number of elements at the very beginning of the unlabeled element that can therefore be a logical relationship with the target number can also be up to (0~6)*6! If the reverse occurs (0~6) *0!+ (0~5) *1!+ .... + (0~0) *6!, existence like 3*0! = = 3*1! Such a cross-border situation
With the knowledge that all elements and collations are available, the Key-value can be used to construct a hash function for one by one mappings, and the resulting pair has good continuity (for example, by using a sequence as a key to derive the corresponding value, then the {a,b,f,e,d,g,c The corresponding value is 87, the original collection {a,b,c,d,e,f,g} all the sequence {a,b,c,d,e,f,g} .... {G,f,e,d,c,b,a} corresponds to a value of 0 .... 5039, of which 7! = 5040,{a,b,c,d,e,f,g} has a size of 7)
Even considering one of the worst states: 6*6!+5*5!+4*4!+3*3!+2*2!+1*1!+0*0! = 5039, haha is not just to protect the lower limit?
The compact double-shot set minimizes the possible waste, and for the above example, an array of array[5040] is just enough, without worrying about the existence of value greater than 5039, which naturally does not necessarily open the array larger, resulting in potentially wasted space inside (for less-than-good hash functions, May be 5,040 burst to the range of 0~10000, if open a array[10000] array although can meet the requirements, but it is necessary to waste 4,960 of the units!!! )
The above is the hash map space compression artifact----Cantor expansion ^. ^
?
Cantor open style [delicious full arrangement]