1. Arranging Questions:
(1) Recursive solution: Take ABC as an example (1). The first character is exchanged with the following character (2). The second character is exchanged with the following character, and (1) is the same as the recursive one.
#include <iostream>using namespace Std;bool isswap (char *str, int s, int k) {for (int i = s; i < K; i++) {if (* (str + i) = = * (str + k) return false;} return true;} void Swap (char &t1, char &t2) {Char temp = T1;T1 = T2;t2 = temp;} void permutation (char *str, int k, int m) {if (str = = NULL) return;if (k = = m) {static int n = 0;n++;cout << n<< " "<<str << Endl;} else{for (int i = k; i < m; i++) {if (Isswap (str,k,i)) {Swap (* (str + k), * (str + i)); Permutation (str, k + 1, m); Swap (* (str + k), * (str + i));}}} int main () {char a[] = "abc"; int len = sizeof (a)/sizeof (a[0]); Permutation (A, 0, len-1); GetChar (); return 0;}
(2) Non-recursive solution:
1. Sort the initial queue to find the smallest permutation pmin in all permutations.
2. Find the arrangement P (min+1) that is just as small as the pmin.
3. Loop through the second step until one of the largest permutations is found and the algorithm ends.
such as arranging ABCDE, this is the smallest of all permutations of an arrangement, just larger than the ABCDE arrangement is: abced.
The algorithm is as follows:
Given the known sequence P = a1a2a3 ..... An
Sort p by dictionary, get a minimum permutation of P pmin =a1a2a3 .... An, satisfying ai > A (i-1) (1 < i <= N)
Starting with Pmin, find a permutation p (min+1) that is just larger than pmin, and then find an arrangement that is just larger than P (min+1), so repeat.
1. From the back forward (i.e. from AN->A1), find the first pair of adjacent elements ascending, i.e. Ai < A (i+1). If this AI is not found, it means that the last full permutation has been found and can be returned.
2. From the back forward, find the first number of AJ that is larger than AI, exchanging AI and AJ.
3. Will be arranged in a (i+1) a (i+2) .... An inverse inversion of the number of this sequence, an ... A (i+2) a (i+1). Because from the previous 1th, 2 can be learned that a (i+1) >=a (i+2) >=.....>=an, which is an ascending sequence, the sequence should be reversed, the resulting new arrangement is just like the previous arrangement of large.
4. Repeat step 1-3 until it returns.
#include <iostream>using namespace Std;int cmp (const void *a,const void *b) {return * (char*) A-* (char*) b;} void Swap (char *a, char *b) {Char temp = *a;*a = *b;*b = temp;} void reverse (char *str, int i,int len) {while (I < len) {swap (str + i, str + len); i++;len--;}} void combination (char *str, int len) {if (Len < 1) return;qsort (str, strlen (str), sizeof (char), CMP); int i = 0;int j = 0; while (true) {cout << str << endl;for (i = len-1; I >= 0; i--) {if (Str[i] < Str[i + 1]) break;if (i = = 0) r Eturn;} for (j = len, J > i; j--) {if (Str[j] > Str[i]) break; Swap (Str[j], str[i]); reverse (str, i + 1,len);}} int main () {char a[] = "BCA"; int len = sizeof (a)/sizeof (a[0]);//permutation (A, 0, len-1); combination (A, len-2); GetChar ( ); return 0;}
2. Combinatorial issues:
(1) Recursive solution: Suppose we want to find a combination of M characters in a string of length n. We first scan the first character of a string. For the first character, we have two options: the first is to put this character in the combination, and then we need to select the m-1 character in the remaining n-1 characters, and the second is not to put the character in the combination, then we need to select M characters in the remaining n-1 characters. Both of these options are easy to implement recursively
#include <iostream> #include <vector>using namespace std;void combination (char *str, int i, Vector<char > &result) {if (i = = 0) {Vector<char>::iterator iter = Result.begin (); for (; ITER! = Result.end (); iter++) cout << *iter;cout << Endl;return;} if (*str = = ') return;result.push_back (*STR) combination (str + 1, i-1, result); Result.pop_back (); combination (str + 1, I, result);} void combination (char *str, int len) {vector<char> result;for (int i = 1; i < Len; i++) {combination (str, I, result );}} int main () {char a[] = "abc"; int len = sizeof (a)/sizeof (a[0]);//permutation (A, 0, len-1); combination (A, Len); GetChar (); re Turn 0;}
(2) Bit arithmetic solution:
#include <iostream>using namespace std;void combination (char *str, int i, int len) {for (int j = 0; J < Len; J + +) {I F (i& (1 << j)) cout << str[j];} cout << Endl;} void combination (char *a, int len) {for (int i = 0; i < (1 << len); i++) {combination (A, I, Len);}} int main () {char a[] = "abc"; int len = sizeof (a)/sizeof (a[0]);//permutation (A, 0, len-1); combination (A, len-1); GetChar (); return 0;}
3. Permutation example (eight Queen's question):
Basic idea:
Since any two of the eight queens cannot be in the same row, then this must be one row for each queen. So we can define an array columnindex[8], and the number I in the array represents the column number of the Queen on line I. First of all, the ColumnIndex eight numbers are initialized with 0-7, the next thing we want to do is the array of columnindex do the whole arrangement. Since we initialize the numbers in the array with different numbers, any two queens definitely have different columns. All we need to know is whether each of the eight queens in the array is on the same diagonal line, that is, the two subscripts I and J, are not i-j==columnindex[i]-column[j] or j-i==columnindex[i]- COLUMNINDEX[J].
#include <iostream>using namespace std;void swap (int *a, int *b) {int temp = *a;*a = *b;*b = temp;} BOOL Check (int *queue, int queuenumber) {for (int i = 0; i < Queuenumber; i++) for (int j = i+1; J < Queuenumber; J + +) {if (i-j = = Queue[i]-Queue[j] | | i-j = = QUEUE[J]-queue[i]) return false;} return true;} void permutation (int *queue, int queuenumber,int begin) {if (begin = = Queuenumber) {if (check (queue, Queuenumber)) {for (int i = 0; i < Queuenumber; i++) cout << queue[i];cout << Endl;}} else{for (int j = begin; J < Queuenumber; J + +) {swap (Queue[begin], queue[j]);p ermutation (queue, queuenumber, begin + 1); Swap (Queue[begin], queue[j]);}} void Eightqueue () {const int queuenumber = 8;int *queue = new Int[queuenumber];for (int i = 0; i < Queuenumber; i++) {que Ue[i] = i;} Permutation (queue, queuenumber, 0);} int main () {char a[] = "abc"; int len = sizeof (a)/sizeof (a[0]);//permutation (A, 0, len-1);//combination (A, len-1); eightque UE (); GetChar (); return 0;}
4. Combination of instances (taken from 1-n and combined with m):
Basic idea: List all combinations, judging the summation of various combinations and.
#include <iostream> #include <vector>using namespace std;void combination (int *a, int n, int m, int i, vector< ;int> &result) {if (i = = 0) {int sum = 0;vector<int>::iterator iter = Result.begin (); for (; ITER! = Result.end ( ); iter++) {sum = sum + *iter;} if (sum = = m) {iter = Result.begin (); for (; ITER! = Result.end (); iter++) {cout << *iter<< ' \ t ';} cout << Endl;} return;} if (*a = = 0) return;result.push_back (*a) combination (A + 1, N, m, i-1, result); Result.pop_back (); combination (A + 1, N, M, I, result);} void combination (int n, int m) {int *a =new int[n+1];vector<int> result;for (int i = 0; i < n; i++) A[i] = i + 1;a[ N] = 0;for (int i = 1; I <= n; i++) combination (A, n, M,i,result); return;} int main () {char a[] = "abc"; int len = sizeof (a)/sizeof (a[0]);//permutation (A, 0, len-1);//combination (A, len-1);//EIGHTQ Ueue (); combination (ten); GetChar (); return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Permutation combination problem