A fully arranged algorithm outputs all the different (n! Such:
Given SEQUENCES {1, 2, 3} Have {1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1}
It seems that it can be easily written. For a longer sequence, it is only a matter of time. In the end, it will certainly be able to be listed one by one with a pen.
However, if you want to implement it in a program, it may be a little difficult (at first glance, it seems very simple). The following three methods are provided to describe the full arrangement:
-------
I. Original Method
The so-called original method is to construct a feasible method completely to solve the problem without considering the algorithm efficiency and other factors (not necessarily, but can solve the problem)
First, let's think about how we wrote the above six sequences.
1. Determine the first element. Three possibilities are available: 1, 2, 3.
2. determine the elements on the second digit (taking 1 as an example). There are two possibilities: 2, 3.
3. Determine the element on the third digit (take 2 as an example). There is only one possibility: 3. Then we get a sequence: 1, 2, 3.
Next, let's take a look and think about how to implement it using a program.
For a sequence whose length is N, what the computer needs to do is
1. determine the elements on the (I) bit. There are (n + 1-I) possibilities. Select one element in sequence as the I bit, save the currently determined sequence (Length: I)
2. determine the elements on the (I + 1) bits. There are (n + 1-I) possibilities. Select one element that may be used as the I + 1 bits in turn, save the currently determined sequence (Length: I + 1)
......
N. Determine the element at the (n) bit. There is only one possibility. The unique possible element is used as the element at the nth bit and the determined sequence is output.
Obviously, this is a recursive method.
The Java code is as follows:
Public class fullpermutation {static int COUNT = 0;/*** implement full recursion * <br/> the program thought is: Determine the first and last places in sequence, consistent with the general way of thinking */public static void main (string [] ARGs) {string STR = "13234"; STR = check (STR ); // remove the duplicate element fullpermutate (0, "", STR); system. out. print (count );} /*** @ Param index this call determines the index position * @ Param path the ordered string * @ Param string the string to be fully ordered */static void fullpermutate (INT index, string path, string) {string rests Tr = strsub (string, PATH); If (Index = string. length () {system. out. println (path + reststr); count ++; // return;} else {for (INT I = 0; I <string. length ()-index; I ++) fullpermutate (index + 1, path + reststr. charat (I), string );}} /*** @ Param full complete string * @ Param part molecular string * @ return rest returns the full and part difference set */static string strsub (string full, string part) {string rest = ""; for (INT I = 0; I <full. length (); I ++) {strin G C = full. charat (I) + ""; if (! Part. contains (c) Rest + = C;} return rest ;} /*** @ Param STR the string to be checked * @ return returns a string without repeated elements */static string check (string Str) {for (INT I = 0; I <Str. length ()-1; I ++) {string firstpart = Str. substring (0, I + 1); string restpart = Str. substring (I + 1); STR = firstpart + restpart. replace (Str. charat (I) + "", "") ;}return STR ;}}
P.s. as to why repeated elements in parameters need to be removed from the Code above, the program's robustness is enhanced. The typical arrangement problem is for sequences without repeated elements, we will discuss the sequence with repeated elements later.
II. General algorithms (the most common and classic full-rank algorithms)
The core idea is exchange. Specifically, for a string with a length of N, we can do this to get all its permutation:
1. Switch the elements in the current BIT with all the elements in the latter order.
2. perform the same processing on the next bit until the current bit is the last bit and the output sequence is
[Note: Our idea is to "Exchange", that is, directly modify the original data, so we must change it back after the exchange, otherwise, our original data will change and errors will surely occur.]
If you think the above explanation is still difficult to understand, remember this sentence: the core idea is to let everyone behind you exchange it with you (and you are a pointer, move from front to back ...)
C code is as follows :( from http://www.cnblogs.com/nokiaguy/archive/2008/05/11/1191914.html)
#include <stdio.h> int n = 0; void swap(int *a, int *b) { int m; m = *a; *a = *b; *b = m; } void perm(int list[], int k, int m) { int i; if(k > m) { for(i = 0; i <= m; i++) printf("%d ", list[i]); printf("\n"); n++; } else { for(i = k; i <= m; i++) { swap(&list[k], &list[i]); perm(list, k + 1, m); swap(&list[k], &list[i]); } } } int main() { int list[] = {1, 2, 3, 4, 5}; perm(list, 0, 4); printf("total:%d\n", n); return 0; }
The original article also provides some explanations, but if you still cannot understand it, you may wish to output the running track to help you understand it, or use a pen to draw it and read it several times, it is hard to understand the Code directly.
3. Lexicographic Method
In fact, in the example given at the beginning of this article, the Lexicographic Order is used unconsciously when people write fully-arranged or other similar things. This is to prevent missing sequences.
In this case, the Lexicographic Order can also be used for full arrangement. For the given sequence {3, 1, 2}, let's take a look at the specific steps:
1. Sort the given sequence in ascending order to obtain the minimum lexicographic orders {1, 2, 3}
2. Find the next Lexicographic Order of the ordered sequence and obtain {1, 3, 2}
3. If the current sequence does not have the next Lexicographic Order (or the current sequence is the largest Lexicographic Order, for example, {3, 2, 1}), it ends.
Obviously, the core of the Lexicographic Order Method is: to find the next Lexicographic Order, we need to fully understand the "Next" here, which has two meanings:
1. The sequence is in the dictionary behind the current sequence
2. The sequence is the closest to the current sequence in the dictionary.
The Lexicographic Order has a strict mathematical definition. You can find the next Lexicographic Order of a sequence according to the definition. The specific practices are not described here (the following code provides a detailed explanation)
The Java code is as follows:
Public class dictionaryorder {/*** output in Lexicographic Order * <br/> the next sequence of known sequences can be obtained in Lexicographic Order, it can be used when no full arrangement is required (for example, data encryption) */public static void main (string [] ARGs) {int arr [] = new int [] {4, 3, 1, 2};/* Boolean exist = nextpermutation (ARR); If (exist) {for (INT value: ARR) system. out. print (value); system. out. println ();} elsesystem. out. println ("the current sequence is already the largest dictionary sequence"); * // sort the given sequence (ascending) sort (ARR); For (INT value: ARR) system. out. print (valu E); system. out. println (); // returns int COUNT = 1. // The first one has output the while (nextpermutation (ARR) {for (INT value: ARR) system. out. print (value); system. out. println (); count ++;} system. out. println ("Total" + Count + ""); // */}/*** @ Param arr current sequence * @ return the next sequence in the lexicographic sequence, false */public static Boolean nextpermutation (INT [] ARR) {int pos1 = 0, pos2 = 0; // 1. find the I that satisfies the requirements of ARR [I] <arr [I + 1] from the right to the left (that is, find the location where the adjacent bits meet the requirements of the former less than the latter) Boo Lean find = false; For (INT I = arr. length-2; I> = 0; I --) if (ARR [I] <arr [I + 1]) {pos1 = I; find = true; break ;} if (! Find) // if not found, it indicates that the current sequence is already the largest lexicographically ordered return false; // 2. find the smallest position that satisfies arr [I]> = arr [pos1] From pos1. // (locate the position that is not smaller than the minimum value of ARR [pos1] After pos1) int min = arr [pos1]; for (INT I = pos1 + 1; I <arr. length; I ++) {If (ARR [I]> = arr [pos1]) {min = arr [I]; pos2 = I ;}// 3. the value int temp = arr [pos1]; arr [pos1] = arr [pos2]; arr [pos2] = temp; // 4. perform reverse processing (transpose) on all values after pos1 int I = pos1 + 1; Int J = arr. length-1; for (; I <j; I ++, j --) {temp = arr [I]; arr [I] = arr [J]; arr [J] = temp;} return true;}/*** sort the given array in ascending order (Bubble Method) * @ Param arr array to be sorted */public static void sort (INT [] ARR) {for (INT I = 0; I <arr. length-2; I ++) for (Int J = 0; j <arr. length-I-1; j ++) if (ARR [J]> arr [J + 1]) {int temp = arr [J]; arr [J] = arr [J + 1]; arr [J + 1] = temp ;}}}
-------
The algorithm details are here, and several irrelevant questions are discussed below:
1. duplicate elements exist in the given sequence
This issue is not discussed in the classic full arrangement, but may be encountered in practical applications. We have two options:
I. process the original data (given sequence), retain only one repeat element, or replace the repeated element, for example, to {1, 1, 2, 3, 2 }, create a replacement table, a = 1, B = 2, and the original data processing result is {1, A, 2, 3, B}. At this point, we have eliminated repeated elements.
Ii. Modify the algorithm, detect duplicate elements, and perform corresponding processing. The algorithm must be processed based on specific data features.
2. algorithm efficiency problems
If you need to use full sorting in a complex problem, you have to consider the algorithm efficiency. In the above algorithm, the first two types of time complexity are the same, both of which are n-layer recursion, n-I + 1 cycle per Layer
The time complexity of the third algorithm is mainly concentrated on sorting. If the given sequence is already ordered, the third algorithm is undoubtedly the best.
In addition, there is a novel full-Rank Algorithm. If you are interested, you can try it:
Http://supershll.blog.163.com/blog/static/37070436201171005758332/