Problem
Enter a string that prints all the permutations of the characters in the string. For example, the input string, ABC, outputs all strings that can be arranged by the character A,b,c Abc,acb,bac,bca,cab and CBA
Ideas
This is a typical recursive solution problem, and the recursive algorithm has four characteristics:
- There must be a attainable termination condition, otherwise the program falls into a dead loop
- The sub problem is smaller than the original problem in scale
- A child problem can be called again by recursive call to solve
- The solution of the sub problem can be combined into the solution of the whole problem
For the arrangement of strings:
If you can generate a full array of n-1 elements, you can generate a full arrangement of n elements. For a set of only one element, you can generate a full arrangement directly. So the recursive termination conditions for all permutations are clear, with only one element. We can analyze the whole arrangement process:
- First, we fixed the first character a, and asked for the two-character BC arrangement.
- When the two-character BC arrangement is made, we swap the first character A and the back B, get BAC, and then we fix the first character B, and then the two-character AC arrangement.
- Now it's time to put C in the first position. But remember that we've swapped the first character A and the second B in the front, to make sure that this time C is still in the first place, and we're going to swap B and a before we swap the C and the first character. After the exchange of B and a, then take C and in the first position of the exchange, get the CBA. We fixed the first character C again, and asked for the arrangement of the two characters B and a.
- Since we already know how to get the three-character arrangement, it's a typical recursive idea to fix the first character after the two-character arrangement.
The following diagram clearly gives a recursive process:
Basic Solution
Method 1: In turn, remove a character from the string as the first character in the final arrangement, generating a full arrangement of the strings of the remaining characters, the final result being a combination of the removed character and the remaining substring.
#include <iostream>
#include <string>
using namespace std;
void permute1 (string prefix, string str)
{
if (str.length () = = 0)
cout << prefix << endl;
else
{
for (int i = 0; i < str.length (); i++)
permute1 (prefix+str[i), Str.substr (0,i) +str.substr (i+1, Str.length ()));
}
void Permute1 (string s)
{
permute1 ("", s);
}
int main ()
{
//method1, unable to remove duplicate permutations.
cout << "method1" << Endl;
Permute1 ("ABA");
}
Advantage: This method is easy to understand, but can not remove duplicate arrangement, such as: s= "ABA", will generate two "AAB".
Method 2: Using the idea of exchange, see concrete examples, but this method is not as easy to understand as Method 1.
#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
void swap (char* x, char* y)
{
char tmp;
TMP = *x;
*x = *y;
*y = tmp;
}
/* function to print permutations of the string this
Function takes three parameters:
1. String
2. Starting index of the string
3. Ending index of the string. *
/void Permute (char *a, int i, int n)
{
int J;
if (i = = N)
printf ("%s\n", a);
else
{
for (j = i; J <= N; j +)
{
if (a[i] = = A[j] && J!= i)//To avoid the generation of repeated permutations, the word story in different places is not exchanged at the same time
continue;
Swap ((A+i), (a+j));
Permute (A, i+1, n);
Swap ((A+i), (a+j)); Backtrack
}
}
int main ()
{
//method2
cout << "method2" << Endl;
Char a[] = "ABA";
Permute (a,0,2);
return 0;
}
Build results for two methods:
Method1
aba
AAB
baa
baa
AAB
aba
method2
aba
AAB
BAA
Here's an example of an ACM topic
Sample Topics
Topic description
Topic Description:
Given a string of different lowercase letters, outputting all permutations of this string.
We assume that there is a ' a ' < ' B ' < ... < ' Y ' < ' z ' for lowercase letters, and that the letters in the given string have been sorted in order from small to large.
input:
Enter only one line, a string of different lowercase letters, and the length of the known string is between 1 and 6.
output:
output all permutations of this string, one for each line. Requires a smaller alphabetical order in the front. The alphabetical order is defined as:
known s = s1s2...sk, t = t1t2...tk, then s < T is equivalent to the existence of P (1 <= p <= k), so that
S1 = t1, s2 = t2, ..., sp-1 = tp-1, SP < TP is established.
Sample input:
abc
sample output:
&nb sp; abc
acb
bac
bca
cab
cba
hint:
&nbs p; output a carriage return after each set of sample output ends.
AC code
#include <stdio.h> #include <stdlib.h> #include <string.h> struct seq {char str
[7];
};
struct SEQ seqs[721];
int count;
void Swap (char *str, int a, int b) {char temp;
temp = Str[a];
Str[a] = str[b];
STR[B] = temp;
} void Permutation_process (char *name, int begin, int end) {int k;
if (begin = = end-1) {strcpy (seqs[count].str, name);
Count + +;
}else {for (k = begin; k < end; K + +) {Swap (name, k, begin);
Permutation_process (name, begin + 1, end);
Swap (name, k, begin);
} int Compare (const void *p, const void *q) {const char *a = p;
const char *b = q;
Return strcmp (A, b);
int main () {char name[7];
int I, Len;
while (scanf ("%s", name)!= EOF) {count = 0;
Len = strlen (name);
Permutation_process (name, 0, Len);Qsort (Seqs, Count, sizeof (seqs[0)), compare);
for (i = 0; I < count i + +) {printf ("%s\n", seqs[i].str);
printf ("\ n");
return 0;
}
/**************************************************************
problem:1120
User:wangzhengyi
Language:c
result:accepted
time:710 ms
memory:920 kb
****************************************************************/
Remove the full array of duplicates
A flaw in the code above is the output of duplicate data, such as ABB's string, which runs the result as shown:
Since the whole arrangement is from the first digit, each number is exchanged with the number behind it, we first try to add this judgment--if a number is the same as the following number, then the two numbers will not be exchanged. For example ABB, the first number is exchanged with the back two numbers bab,bba. Then ABB's second and third numbers are the same, so there's no need to swap. But for Bab, the second and third numbers are different, they need to be exchanged to get BBA. This method does not work because the BBA and first numbers here are the same as the result of the exchange of the third number.
In another way, for ABB, the first number A is exchanged with the second number B, and then the first number is exchanged with the third number, at which point the first number is no longer exchanged with the third number because the third number equals the second number. Bab Consider Bab, whose second number is exchanged with the third number to resolve the BBA. At this time the full arrangement of the build finished!
In this way, we get rid of the duplicate rule in the full arrangement:
The whole arrangement of the weight is from the first digit, and each number is exchanged with the number that does not recur after it.
To post the version of the above AC code:
#include <stdio.h> #include <stdlib.h> #include <string.h> struct seq {char str[
7];
};
struct SEQ seqs[721];
int count;
int Is_swap (char *str, int begin, int k) {int i, flag;
for (i = begin, flag = 1 I < K; i + +) {if (str[i] = = Str[k]) {flag = 0;
Break
} return flag;
} void Swap (char *str, int a, int b) {char temp;
temp = Str[a];
Str[a] = str[b];
STR[B] = temp;
} void Permutation_process (char *name, int begin, int end) {int k;
if (begin = = end-1) {strcpy (seqs[count].str, name);
Count + +; }else {for (k = begin; k < end; K + +) {if (Is_swap (name, begin, K)) {Swap (name, K, Begin)
;
Permutation_process (name, begin + 1, end);
Swap (name, k, begin); int compare (const void *p, const void *Q)
{const char *a = p;
const char *b = q;
Return strcmp (A, b);
int main () {char name[7];
int I, Len;
while (scanf ("%s", name)!= EOF) {count = 0;
Len = strlen (name);
Permutation_process (name, 0, Len);
Qsort (Seqs, Count, sizeof (seqs[0)), compare);
for (i = 0; I < count i + +) {printf ("%s\n", seqs[i].str);
printf ("\ n");
return 0;
}