Algorithm learning (I) Multiple fully-arranged Recursive Algorithms and Recursive Algorithms
Full sorting is a primary issue in algorithm learning and also a hot issue for IT companies in recent years. Recently, due to a friend's actual problem, I used an algorithm similar to the full arrangement, so I would like to summarize the relevant code.
I. Problem Description
The problem of full arrangement is very simple. For example, if three numbers 1, 2, and 3 are given, please combine all the three numbers in order of size. The expected result is 123,132,213,231,312,321.
Ii. Analysis of the First Recursive Algorithm
For the given n numbers, there are obviously n! . The key lies in how to arrange all the data. One obvious way is to first select the number on the first digit, then backtrack the number on the second digit, and then select the third digit ...... You only need to make sure that the numbers selected on each digit are not repeated. This algorithm is easy to understand and has a better design for recursion. First, use the code (c ++ ):
1 #include<iostream> 2 #include<fstream> 3 using namespace std; 4 5 ifstream fin; 6 ofstream fout; 7 int flags[100]; 8 int numbers[100]; 9 int n;10 11 void search(int loc){12 if(loc==n){13 fout<<numbers[0]+1;14 for(int i=1;i!=n;i++)15 fout<<","<<numbers[i]+1;16 fout<<endl;17 }else{18 for(int i=0;i!=n;i++)19 if(flags[i]){20 flags[i]=0;21 numbers[loc]=i;22 search(loc+1);23 flags[i]=1;24 }25 }26 }27 28 int main(){29 30 //fin.open("input.txt",ios::in);31 fout.open("QPL.txt",ios::out);32 33 cin>>n;34 for(int i=0;i!=n;i++)35 flags[i]=1;36 search(0);37 }
The key to an algorithm is the implementation of the search function. The first step is to determine the exit condition. The search function fills in a number from left to right in each pit. When loc = n, it fills in all the pits. This sorting is complete. Then fill in the number in each pit, that is, the for loop. Fill in the number from 0 to n for each pit, and judge that there is no repeated use.
The advantage of this implementation is that it is more intuitive and scalable. You can try to modify the boundary criterion.
Iii. Analysis of the second Recursive Algorithm
There is also such a seemingly concise recursive algorithm on the Internet. The algorithm observes the generation mode of full sorting. Taking 123 as an example, its full sorting column is 123,132,213,231,312,321. through observation, we can find that 123 of the full sorting is 1 + (full arrangement of 23) + 2 + (full arrangement of 13) + 3 + (full arrangement of 12) here the Recursive Design is 1 + perm (23) and then exchange 1 and 2 and then execute 2 + perm (13) and then exchange 2 and 3 to execute 3 + perm (23 ).
The Code is designed as follows:
1 # include <iostream> 2 # include <fstream> 3 # include <stdlib. h> 4 5 using namespace std; 6 7 void swap (char * a, char * B) 8 {9 char temp; 10 temp = * a; 11 * a = * B; 12 * B = temp; 13} 14 15 void Perm (char * pszStr, int k, int m) 16 {17 if (k = m) 18 {19 static int s_ I = 1; 20 cout <"the" <s_ I ++ <"line" <pszStr <endl; 21} 22 else23 {24 for (int I = k; I <= m; I ++) // The number I is exchanged with the number next to it to obtain a new 25 {26 swap (pszStr + k, pszStr + I); 27 Perm (pszStr, k + 1, m); 28 swap (pszStr + k, pszStr + I); // restore site 29} 30} 31} 32 33 int main (int argc, const char * argv []) 34 {35 char str [] = "1234"; 36 Perm (str, 0, 3); 37 return 0; 38}
C language: analysis of this fully-arranged Recursive Algorithm
Used array is a global variable with an implicit initial value of 0;
You can understand the fully arranged algorithms as deep search and backtracking.
# Include <stdio. h>
# Define MAX 10
Int used [MAX]; // used to mark whether a number has been used before
Int result [MAX]; // store the result
Int N;
Void print () // output result
{
Int I;
For (I = 0; I <N; I ++)
Printf ("% d", result [I]);
Printf ("\ n ");
}
Void proc (int step) // step is used to record the number of records already set
{
Int I;
If (step = N) // if the number of N has been set, the result is generated and the result is output.
Print ();
Else
{
For (I = 0; I <N; I ++) // enumeration 1-N, find the minimum number that has not been used
{
If (! Used [I]) // never used
{
Used [I] = 1; // mark I used
Result [step] = I + 1; // record the result
Proc (step + 1); // recursive Solution
Used [I] = 0; // here is the so-called backtracking, which may be difficult to understand. You can go through it manually to deepen your understanding. In fact, the main idea of backtracking is "restoring the scene ". when this step is executed, the number I + 1 is placed at the position of step 1, and we need to take out the number I + 1 and mark it as unused.
}
}
}
}
Int main ()
{
Scanf ("% d", & N );
Proc (0 );
Return 0;
}
Which of the following algorithms can help me understand the fully arranged Recursive Algorithms? Thank you!
Do you know what the recursive program means?
That is, first control the rest, arrange the remaining, then move the first, and then arrange the remaining
This program also means this.
For example, 1234
1. First keep 1 unchanged, arrange 234
2. Keep 2 unchanged, arrange 34
3. Keep 3 unchanged, arrange 4
4. 4; Output 1234.
5. Jump to 3 and Switch 3 to 4,
6. 3 is displayed. The output value is 1243.
7. Jump to 2, swap 2 and 3,
8. Repeat 3-6 and get and.
9. Jump to 2 and switch 2 to 4 to get 1423,1432.
The following steps are omitted ..
The final result is a full array.
Answered
A better full-Rank Algorithm (c)-| killniu published on 23:39:00
I have a better full-ranking algorithm. I have verified that the results 3, 4, and 5 are correct.
The program does not use recursion, but only a few loops, the speed is satisfactory.
On C466A and Win2000 machines, 8 numbers are arranged in full order and the results are not displayed. redirection to a text file takes less than one second.
. It takes 6 seconds to sort all the nine numbers. 10 digits in 55 seconds. (The above results are not displayed and all are redirected to a text file)
It takes about 16 seconds to fully arrange the 11 numbers (the results are not displayed, and ISPRINT is not defined in the original program.
.
Thank you for your advice.
The algorithm is as follows: two arrays are used. One array stores the current result. The second array indicates whether each number is used. For example
Rows are arranged in full order. The first result is: 0 1 2 3 4 5 6 7 8 9.
Then, set the flag of each number to 1.
Then start the main loop:
Print the current result first.
In the previous result, find the first number in the ascending order from the back to the top. Indicates the use of numbers placed in the current position every time a request is made.
0, and then find the first number that is greater than this number but has not been used.
For example, if the first result is 4 1 9 7 8 2 5 0 6 3, then the first number from the back to the top is 0, and the first one is greater than 0, but no
The number used is 3 (because there are only 6 and 3 numbers greater than 0 ). Finally, the unused numbers are printed in ascending order. So next
The result is 4 1 9 7 8 2 5 3 0 6.
The source code is (compiled successfully under BC ++ 3.0 ):
# I nclude <stdio. h>/* these two library functions are habitually added into _ ^. */
# I nclude <stdlib. h>
# Define ISPRINT/* Indicates whether to print the result */
# Define MAX 200/* Maximum Number */
Unsigned int * _ NUM;/* array pointer used to store a result */
Char * _ NUMFLAG;/* used to store the used flag */
# Define NUM (j) (* (_ NUM + (j)/* number at the j position */
# Define NUMFLAG (j) (* (_ NUMFLAG + (j)/* indicates whether the number j has been used. 0 indicates that it is not used, and 1 indicates that it is used */
# Define NUMUSE (j) (* (_ NUMFLAG + (* (_ NUM + (j)/* indicates whether the number on the j-digit is used, 0 is not used, 1 is already
Used */
Void main ()
{
Unsigned int number, j;
Int I;
Printf ("Input number ="); scanf ("% u", & number );
If (number> = MAX) | (number <= 1) {puts (& quot ...... remaining full text>