Algorithm for Generating Full Permutation (3)

Source: Internet
Author: User

An algorithm based on the full permutation of factorial numbers is another algorithm that outputs the Full Permutation through sequence order. The so-called factorial number is actually the same as the commonly used binary, octal, 10-hexadecimal, and hexadecimal values. It is a numerical representation. What's different is that, in the preceding hexadecimal numbers, the hexadecimal value between adjacent bits is a fixed value. Taking the hexadecimal value as an example, the hexadecimal value between the nth bit and the nth plus 1 bit is 10, the factorial number is a variable value between two adjacent digits. The hexadecimal value between the nth and nth plus 1 is (n + 1 )!. For the decimal number, the value range of each digit is also fixed ~ 9, and the value range of each factorial is 0 ~ N. It can be proved that any number can be uniquely represented by a factorial. The following uses 23 as an example to describe its representation in various hexadecimal formats.

  Binary Octal Decimal Hexadecimal Factorial
23 10111 27 23 17 3210

The calculation method of the number represented by 10-in-23 is

D (23) = 2x10 ^ 1 + 3x10 ^ 0 = 2x10 + 3X1 = 23

The calculation method of the number represented by a factorial of 3210 is as follows:

F (3210) = 3 × 3! + 2 × 2! + 1 × 1! + 0 × 0! = 3x6 + 2X2 + 1x1 + 1x0 = 23

For a factorial, because the growth speed of a factorial is very fast, the range of values that can be expressed is very fast with the increase of digits. For a factorial Number of N bits, the range is from 0 ~ (N + 1 )! -1, total (n + 1 )! Number. The factorial number has many properties. Here we only introduce some of its properties related to the full permutation.

The first is the addition operation, which is basically the same as the addition of the ordinary decimal number. The difference is that for the nth bits f [N] (the decimal bits start from the 0th bits ), if f [N] + 1> N, then we need to set f [N] to 0 and make f [n + 1] + 1. If for the nth + 1 digit, it also leads to carry, and the carry operation is performed in turn to the high bit. Let's take a look at F (3210) + 1. For 0th bits, F [0] + 1 = 0 + 1 = 1> 0, so f [0] = 0 (in fact, the first digit of the factorial number is always 0), f [1] + 1 = 1 + 1 = 2> 1, f [1] = 0 ,......, Execute in sequence, where all carry occurs. The final result is F (3210) + 1 = f (10000 ).

Secondly, for the number of factorial of N bits, the values of each factorial exactly correspond to the inverse relationship of N orders. Here we use ABCD as an example. For example, F (2110) means that for the first element in the arrangement, there are two elements smaller than him. For the second element, an element is smaller than him. The third element is smaller than him. Finally, the cbda is constructed based on F (2110. The relationship between the 4-digit factorial and the 4-digit permutation is shown in the following table.

0000 ABCD 1000 Bacd 2000 CABD 3000 Dabc
0010 ABDC 1010 BADC 2010 Cadb 3010 Dacb
0100 Acbd 1100 Bcad 2100 Cbad 3100 Dbac
0110 ACDB 1110 BCDA 2110 Cbda 3110 Dbca
0200 ADBC 1200 Bdac 2200 Cdab 3200 Dcab
0210 Adcb 1210 Bdca 2210 Cdba 3210 Dcba

As a result, we can use the correspondence between the factorial number and the arrangement to construct the full arrangement of the set. The algorithm is as follows.

  • For the full arrangement of n elements, first generate the n-bit factorial number f [0... n-1] And set f [0... n-1] to 0.
  • Each time you perform the + 1 operation on f [0... n-1], the result is generated based on the inverse relationship between the result and the arrangement.
  • Until f [0... n-1] reaches the maximum number of n! -1 till all n! The sorting is completed.

There is a problem to be solved here, that is, how to generate a corresponding arrangement based on the factorial number and its correspondence with the reverse order of the Arrangement. Here is a method,

  • With the smallest Lexicographic Order of a [0... n-1] as the starting point, let I from 0 to N-2.
  • If f [I] = 0, increment I.
  • Otherwise, make T = A [I + F [I], and set a [I... the elements in the I + F [I]-1] interval move one digit backward, then a [I] = T, increasing I.

The following describes how to create a proper arrangement based on the factorial F (2110) and the initial arrangement of ABCD. First, we find that f [0] = 2, so we need to place the element C at the position of a [0 + 2] in the position of a [0]. Before that, use the temporary variable t to record the value of a [2], and then set a [0... the elements in the range 0 + 2-1] Move one digit backward, and then make a [0] = t to get CABD. The I value is increased by 1; then f [1] = 1, so we need to place a [1 + 1] = A [2] = B in the position of a [1, at the same time, move a [1] Backward to get the cbad arrangement. Then, F [2] = 1, therefore, place a [2 + 1] = A [3] = d in the position a [2], and a [2] moves one digit backward. Finally, the cbda is obtained, and the order generation is complete. The entire algorithm code is as follows:

Inline int facnumnext (unsigned int * facnum, size_t array_size) {unsigned int I = 0; while (I <array_size) {If (facnum [I] + 1 <= I) {facnum [I] + = 1; return 0;} else {facnum [I] = 0; + + I ;}} return 1 ;} /** build and arrange the output according to the reverse order specified by the factorial according to the original string */inline void buildperm (const char * array, size_t array_size, const unsigned int * facnum, char * out) {char t; unsigned int I, j; memcpy (Out, array, array_size * sizeof (char); for (I = 0; I <array_size-1; ++ I) {J = facnum [array_size-1-I]; If (J! = 0) {T = out [I + J]; memmove (out + I + 1, out + I, j * sizeof (char )); out [I] = T ;}}/ ** generates an algorithm based on the full arrangement of factorial (Reverse Order) */void fullarray (char * array, size_t array_size) {unsigned int facnum [array_size]; Char out [array_size]; for (unsigned int I = 0; I <array_size; ++ I) {facnum [I] = 0 ;} buildperm (array, array_size, facnum, out); For (unsigned int I = 0; I <array_size; ++ I) {cout <out [I] <'';} cout <'\ n'; while (! Facnumnext (facnum, array_size) {buildperm (array, array_size, facnum, out); For (unsigned int I = 0; I <array_size; ++ I) {cout <out [I] <'';} cout <'\ n ';}}

Use this algorithm to generate a 1234-level full-order chart. The sequence is as follows: The image is from Wikipedia.

From the perspective of generating the order of arrangement, the estimation method has obvious advantages over the Lexicographic Order and minimum change, but in practical application, because the reverse order defined by the factorial is an O (N ^ 2) time complexity process, the overall execution efficiency of the algorithm is inferior. However, the idea of establishing the correspondence between the reverse order number and the arrangement by the factorial number is very exciting and worth learning from.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.