The law of programming 1.3 full array of strings, combinations, repeats, eight queens questions

Source: Internet
Author: User

Title Description: Enter a string that prints out all the permutations of the characters in the string, such as input "abc", Output "abc", "ACB", "BAC", "BCA", "Cab", "CBA"

Solution One: Recursive implementation
Similar to the graph of depth traversal search perfection path algorithm, each Exchange two number, and output, in accordance with the recursive method, such as the full ordering of ABCD, 1: First to find the ABCD after the BCD of the full array (the same first for the B after the CD's full arrangement, then B and the following elements in turn); 2: After AB Exchange BACD after the ACD full arrangement (also first for a after the CD of the full arrangement, and then A and the following elements in turn); 3: First AC-switched Cbad after the bad full array (the same as the first B after the full array of ad, and then B and the following elements in turn); 4: The DBCA after the ad Exchange is fully arranged (again the full arrangement of the CA after B, then the B and the subsequent elements are exchanged in turn).
The time complexity is O (n!).

#include <iostream> #include <string>using namespace std;void allpermutation (string &str, int start, int End) {if (start = = end) {cout << str << endl;return;} int i;for (i = start; I <= end; i++) {swap (Str[start], str[i]); Allpermutation (str, start+1, end), swap (Str[start], str[i]);}} int main () {string str;while (cin >> str) {if (str.size () = = 0)//String length 0 returns the break directly; Allpermutation (str, 0, Str.size ()-1);} return 0;}
Solution Two: Order by dictionary order
such as the full arrangement of the output ZAF, first sort to AFZ, and then the dictionary order output: AFZ, AZF, FAZ, Fza, ZAF, ZFA. The time complexity is O (n!).
Algorithm idea for the next dictionary string for the current string: (Take 967812543 for example)
1, find the first position of the last successive ascending order pairs in the arrangement I; as the above 67,78 and 12,25 are ascending order pairs, where 25 is the last ascending subsequence, so I is the subscript 5 where I is 2.
2, find out the last position of the position I after the AI is greater than the location of J; If the above i=5,ai=2, then I right than the AI has 5,4,3, choose the last position larger than AI, that is, J 3 is the subscript 8.
3, the corresponding elements of the exchange I and J, and then the first i+1 to the last part of the flip, because I is the last ascending order to the first position, the following must be all in descending order, such as the first Exchange 2 and 3, to 967813542, in the subscript 6 starts the remaining substring inverse, Becomes 967813245.
#include <iostream> #include <string> #include <algorithm>using namespace Std;void allpermutation ( char *str, int num) {int i, j;//output current sequence for (i = 0; i < num; ++i) cout << str[i];cout << endl;//Find Next dictionary sequence//Find Ifo R (i = num-2; I >= 0; i) if (Str[i] < str[i+1]) break;//recursive end condition: jumps out of recursion, indicating that the string in Str is now in full descending order if (I < 0)       return;//looking for jfor ( j = num-1; J >= I+1; --J) if (Str[j] > str[i]) break;//swap the corresponding element of i,j and reverse the string after subscript I (Str[i], str[j]); reverse (str+i+1, str+num); Call Allpermutation (str, num) for the standard function template like the sort function;} int main () {char str[110];while (cin >> str) {int num = 0;while (str[num]) ++num;//note Do not write while (str[num++]); if (num = = 0) A string length of 0 directly returns Break;sort (STR, str+num);//Note to sort allpermutation (str, num) first;} return 0;}


Extrapolate

1, all permutations of the dictionary order: each character of the input string is known to be different, and all its combinations are output in dictionary order. If you enter AA, the output aa,ab,ba,bb.
Solution One:
first analyze ABC: Output AAA,AAB,AAC,ABA,ABB,ABC,ACA,ACB,ACC,BAA ..., can analyze the law
Assign an array ans[] to hold the new string, the same recursion, the critical condition of the recursion is that all the characters in the output string are equal, and that the character is the largest character of the original string, and the original string str[], it is obvious that the first ans is all composed of the smallest characters, such as ans[] = {A , a,a...a}.
How to find the next dictionary-ordered string for the current string:
First set a global ascending pointer J in str[] to loop to the right, assigning the initial value to the second character in str[]
A, if the last element of ans[] is less than str[n-1] (the largest element in the string), swap str[j] and ans[num-1], and then J moves forward and into the next recursion, as AaB becomes Aac,aba into ABB
b, if the last element of ans[] is equal to str[n-1], a custom function can be called, which is the function of the pointer I points to ans[] the last position, so that I refers to the element ans[] to str[0], and the pointer I forward, if ans[i] is still equal to str[i-1], After making it equal to str[0], continue to move forward to Ans[i]<str[i-1], at which point Str[i] is assigned to a slightly larger character, and at this point re-j=0, such as ACC into a BAA.
The complexity of the algorithm, the time complexity is O (n^n*n) = O (n^n), due to the need to output n^n results, and each recursion to iterate through an array.
 #include <iostream> #include <string> #include <algorithm>using namespace Std;int j;char str[110], ans[110]; void Access (int cur, int num) {while (ans[cur] = = Str[num-1]) {ans[cur] = str[0];--cur;} int i;for (i = 0; i < num; i++) if (ans[cur] = = Str[i]) Break;ans[cur] = Str[i+1];j = 0;} void allpermutation (int num) {int i;//first outputs the current string for (i = 0; i < num; ++i) cout << ans[i];cout << endl;//critical condition int Flag = 0;for (i = 0; i < num; ++i) if (ans[i]! = str[num-1]) flag = 1;if (!flag) return;//interchange Ans[num-1],str[j]if (Ans[num-1] &l T STR[NUM-1]) ans[num-1] = str[j];elseaccess (num-1, num); ++j;if (j = = num) j = 0; Allpermutation (num);} int main () {while (cin >> str) {int num = 0;while (str[num]) ++num;//note Do not write while (str[num++]); if (num = = 0)// A string length of 0 directly returns Break;sort (STR, str+num); int i;for (i = 0; i < num; ++i) ans[i] = Str[0];j = 1; Allpermutation (num);} return 0;} 

2, all combinations of characters: such as input "abc", Output "a", "B", "C", "AB", "AC", "BC", "ABC".

Solution One: we want to separate a combination of length 1, a combination of length 2, ..., a combination of length n. Consider one of these cases, such as when the length is k, and we can consider it in two different situations:
A, if the composition contains the first character, select K-1 characters from all remaining n-1 characters;
b, if the group does not contain the first character, select K characters from the remaining n-1 characters.
This can be solved recursively by using vectors to hold values that have been added to the current combination, as in the following, remember combination this mode (critical---output and return-to-join current character and recursively--remove the current character and recursively), This mode is also used when the number of numbers added equals a fixed number.
There are two return conditions: 1, such as 1,2,3,4,5 in the length of a combination of 3, at this time the vector collected only 4, 5, it is clear that recursion will cause the subscript overflow, 2, just a certain recursion in the k==0, the array may also have characters may just not have, this time and directly output, if just right now POS =num-1, recursion can also cause subscript overflow, preferably return.
 #include <iostream> #include <vector>using namespace std;vector<char> result;int num;void combination (char * STR, int pos, int k) {if (pos = = num && k! = 0)//There are two return conditions: critical condition return;if (k = = 0) {Vector<char>::iterator iter = R Esult.begin (); for (; Iter < Result.end (); ++iter) cout << *iter;cout << Endl;return; This is also required to return, otherwise str[pos]=str[num] may not be defined}result.push_back (Str[pos]); Combination (str, pos+1, k-1); Select the remaining k-1 characters from the pos+1 of the string subscript result.pop_back (); Combination (str, pos+1, k); Select the remaining K characters after the string subscript pos+1}int Main () {char str[110];while (cin >> str) {num = 0;while (Str[num]) num++;if (num = = 0) Break;int i;for (i = 1; I <= num; ++i) combination (str, 0, i);} return 0;} 
Solution Two: in the case of ABC, if three characters a,b,c respectively corresponds to a binary number No. 0, 1, 2 bits, then the binary 001 for "a", the binary 010 for "B", the binary 011 for "AB", the binary 100 for "C",... 111 means "ABC", in other words, any number in the 1~7 corresponds to a combination of the original string.
Based on mathematical knowledge: the number of combinations of strings of length n = c1/n + c2/n + ... + cn/n = 2^n-c0/n = 2^n-1;, so only the number of 1~2^n-1 to traverse, for the range of a k, analysis of its bits in the 0~n-1 bit is 1, then the output The corresponding character in str[], and which is 0, is skipped.
#include <iostream> #include <cmath>using namespace std;void combination (char *str, int n) {int num = (int) POW ( 2.0, N)-1;int I, j;for (i = 1; I <= num; ++i) {for (j = 0; J < N; j + +) {if (I & (1 << j))//note:& is bitwise AND, & ;& is logic and (overall logical judgment) cout << str[j];} cout << Endl;}} int main () {char str[110];while (cin >> str) {int n = strlen (str); Combination (str, n);} return 0;}


Related Topics:

1, to find the opposite vertex and equal array of the cube:Enter an array of 8 digits placed on the 8 vertices of the cube, making the 4 vertices on the opposite sides of the cube equal to each other, i.e.:
a1+a2+a3+a4=a5+a6+a7+a8; a1+a3+a5+a7=a2+a4+a6+a8; a1+a2+a5+a6=a3+a4+a7+a8.
Solution: To the 8 number of the whole arrangement, for each of the full array of conditions to judge, the judgment is set to output, otherwise do nothing.

#include <iostream>using namespace Std;bool isequal (int nums[]) {int sum1 = Nums[0] + nums[1] + nums[2] + nums[3];    int sum2 = nums[4] + nums[5] + nums[6] + nums[7];    int sum3 = Nums[0] + nums[2] + nums[4] + nums[6];    int sum4 = nums[1] + nums[3] + nums[5] + nums[7];    int SUM5 = Nums[0] + nums[1] + nums[4] + nums[5];    int SUM6 = nums[2] + nums[3] + nums[6] + nums[7];    if (sum1 = = sum2 && sum3 = = sum4 && SUM5 = sum6) return true; else return false;} void allpermutation (int *nums, int start, int end) {if (start = = end) {if (IsEqual (nums)) {int i;for (i = 0; I <= end; ++i) CO UT << nums[i] << ""; cout << Endl;} return;} int i;for (i = start; I <= end; i++) {swap (Nums[start], nums[i]); Allpermutation (Nums, start+1, end); Swap (Nums[start], nums[i]);}} int main () {int nums[110], n;while (CIN >> nums[0]) {//Enter 8 numbers representing 8 vertices of the cube int i;for (i = 1; I <= 7; ++i) CIN >> num T[n]; Allpermutation (nums, 0, 7);} return 0;}
2, eight queens question
problem Description: Put eight queens on 8 X 8 chess, so that they cannot attack each other, that is, any two queens must not be on the same line, on the same column or on the same diagonal, to find all the conditions of the pendulum.
Problem Analysis: Any two queens must not be in the same row, so that each queen can occupy a single row. We can define an array columnindex[8], where columnindex[i] indicates that the Queen in the line I position corresponds to the columnindex[i] column, for example COLUMNINDEX1 = 3 for the Queen in line 1th on column 3rd. Next, the columnindex is initialized with the 0~7 8 numbers respectively. Note that at this time all the queens are not in line with each other. Therefore, we only need to fully arrange the columnindex array to determine whether the position of the 8 queens corresponding to each arrangement is on the diagonal.

#include <iostream> #include <string>using namespace std;bool isnodiag (int *nums) {int i, J;    for (int i = 0, i < 8; i++) {for        (int j = i + 1; j < 8; J + +) {            if (i-j = = Nums[i]-Nums[j] | | i-j = NUMS[J ]-nums[i]) return false;}}    return true;;}  void allpermutation (int *nums, int start, int end) {//Critical condition if (start = = end) {if (Isnodiag (nums)) {int i;for (i = 0; I <= end; ++i) cout << "(" << I << "," << Nums[i] << ")" << "" cout << Endl;} return;} Next recursive int i;for (i = start; I <= end; ++i) {swap (Nums[start], nums[i]); Allpermutation (Nums, start+1, end); Swap (Nums[start], nums[i]);}} int main () {int nums[8] = {0, 1, 2, 3, 4, 5, 6, 7}; Allpermutation (nums, 0, 7);}




The law of programming 1.3 full array of strings, combinations, repeats, eight queens questions

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.