A permutation, also called an “arrangement number” or “order,” is a rearrangement of the elements of an ordered list S into a one-to-one correspondence with S itself. A string of length n has n! permutation.
Below are the permutations of string ABC.
ABC ACB BAC BCA CBA CAB
The following code of all possible string permutation is coded using backtracking , but its not working , anyone please suggest necessary changes.
C program to print all permutations with duplicates allowed -
#include <stdio.h>
#include <string.h>
/* Function to swap values at two pointers */
void swap(char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
/* Function to print permutations of 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 l, int r)
{
int i;
if (l == r)
printf("%s\n", a);
else
{
for (i = l; i <= r; i++)
{
swap((a+l), (a+i));
permute(a, l+1, r);
swap((a+l), (a+i)); //backtrack
}
}
}
/* Driver program to test above functions */
int main()
{
char str[] = "ABC";
int n = strlen(str);
permute(str, 0, n);
return 0;
}
This is a classic case of OBOB (Of By One Bug).
The index of the last character of a n-length string is n-1, so when looping over all indices inside your string, the loop shouldn't be for (i = l; i <= r; i++), but for (i = l; i < r; i++).
Calling swap() with an index that is too big, creates weird effects, such as making your string shorter.
This is the permute() function after the change:
void permute(char *a, int l, int r)
{
int i;
if (l == r)
printf("%s\n", a);
else
{
for (i = l; i < r; i++) // corrected indices
{
swap((a+l), (a+i));
permute(a, l+1, r);
swap((a+l), (a+i)); //backtrack
}
}
}
It should work now.
Related
I am learning backtracking and recursion and I am stuck at an algorithm for printing all the permutations of a string. I solved it using the bell algorithm for permutation but I am not able to understand the recursion method. I searched the web and found this code:
void permute(char *a, int i, int n)
{
int j;
if (i == n)
printf("%s\n", a);
else
{
for (j = i; j <= n; j++)
{
swap((a+i), (a+j));
permute(a, i+1, n);
swap((a+i), (a+j));
}
}
}
How is this algorithm basically working I am unable to understand? I even tried dry running!
How is the backtracking applied?
And is it more efficient than the Bell Algorithm for calculation of permutation?
The algorithm basically works on this logic:
All permutations of a string X is the same thing as all permutations of each possible character in X, combined with all permutations of the string X without that letter in it.
That is to say, all permutations of "abcd" are
"a" concatenated with all permutations of "bcd"
"b" concatenated with all permutations of "acd"
"c" concatenated with all permutations of "bad"
"d" concatenated with all permutations of "bca"
This algorithm in particular instead of performing recursion on substrings, performs the recursion in place on the input string, using up no additional memory for allocating substrings. The "backtracking" undoes the changes to the string, leaving it in its original state.
The code has 2 problems, both related to n, the assumed length of the string. The code for (j = i; j <= n; j++) { swap((a+i), (a+j)); ... swap in string's null character '\0' and gives code truncated results. Check the original (i == n) which should be (i == (n-1)).
Backtracking is applied by calling swap() twice effective undoing its original swap.
The order of complexity is the same for Bell Algorithm.
#include <stdio.h>
void swap(char *a, char *b) { char t = *a; *a = *b; *b = t; }
void permute(char *a, int i, int n) {
// If we are at the last letter, print it
if (i == (n-1)) printf("%s\n", a);
else {
// Show all the permutations with the first i-1 letters fixed and
// swapping the i'th letter for each of the remaining ones.
for (int j = i; j < n; j++) {
swap((a+i), (a+j));
permute(a, i+1, n);
swap((a+i), (a+j));
}
}
}
char s[100];
strcpy(s, "ABCD");
permute(s, 0, strlen(s));
The code that you found is correct! The algorithm swaps the current character in the string with all the subsequent characters and recursively calling the function. Its difficult to explain in words. The figure below may be of some help to you.
Backracking is being done in the 2nd swap for reversing the effect of the 1st swap i.e. we are going back to the original string and will now swap the next character in the array with the current character. The time complexity of the algo. is O(n*n!) since the loop runs n times and the permute function is called n! times. (For the 1st iteration, its called n times; for 2nd iteration (n-1) times and so on).
Source: http://www.geeksforgeeks.org/write-a-c-program-to-print-all-permutations-of-a-given-string/
Recursion really simplifies it:
public static void permutation(String str)
{
permutation("", str);
}
private static void permutation(String prefix, String str)
{
int n = str.length();
if (n == 0) {
System.out.println(prefix);
} else {
for (int i = 0; i < n; i++)
permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n));
}
}
Pseudo code:
String permute(String a[])
{
if (a[].length == 1)
return a[];
for (i = 0, i < a[].length(); i++)
append(a[i], permute(a[].remove(i)));
}
I create more specific but not efficient Program for permutation for general string.
It's work nice way.
//ubuntu 13.10 and g++ compiler but it's works on any platform and OS
//All Permutation of general string.
#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>
using namespace std;
int len;
string str;
void permutation(int cnum)
{
int mid;
int flag=1;
int giga=0;
int dead=0;
int array[50];
for(int i=0;i<len-1;i++)
{
array[50]='\0';
dead=0;
for(int j=cnum;j<len+cnum;j++)
{
mid=j%len;
if(mid==cnum && flag==1)
{
cout<<str[mid];
array[dead]=mid;
dead++;
flag=0;
}
else
{
giga=(i+j)%len;
for(int k=0;k<dead;k++)
{
if((array[k]==giga) && flag==0)
{
giga=(giga+1)%len;
}
}
cout<<str[giga];
array[dead]=giga;
dead++;
}
}
cout<<endl;
flag=1;
}
}
int main()
{
cout<<"Enter the string :: ";
getline(cin,str);
len=str.length();
cout<<"String length = "<<len<<endl;
cout<<"Total permutation = "<<len*(len-1)<<endl;
for(int j=0;j<len;j++)
{
permutation(j);
}
return 0;
}
# include <stdio.h>
/* Function to swap values at two pointers */
void swap (char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
/* Function to print permutations of 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++)
{
swap((a+i), (a+j));
permute(a, i+1, n);
swap((a+i), (a+j)); //backtrack
}
}
}
/* Driver program to test above functions */
int main()
{
char a[] = "ABC";
permute(a, 0, 2);
getchar();
return 0;
}
def perms(s):
if len(s) < 1:
return [s]
ps = []
for i in range(0, len(s)):
head, tail = s[i], s[0:i] + s[i + 1:]
ps.extend([head + tailp for tailp in perms(tail)])
return ps
I would like to know how a recursive function called in a loop of its own definition could be optimized like a tail call so as not to suffer from performance and stack size.
Typically, with pseudo code:
fun example(x):
if (something):
return // Stop the recursion
else:
for (/*...*/):
example() // Recursive call
For a concrete example, I would like to know how to apply such an optimization on the following program, found here:
// C program to print all permutations with duplicates allowed
#include <stdio.h>
#include <string.h>
/* Function to swap values at two pointers */
void swap(char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
/* Function to print permutations of 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 l, int r)
{
int i;
if (l == r)
printf("%s\n", a);
else
{
for (i = l; i <= r; i++)
{
swap((a+l), (a+i));
permute(a, l+1, r); // Recursive call to be optimized
swap((a+l), (a+i));
}
}
}
/* Driver program to test above functions */
int main()
{
char str[] = "ABC";
int n = strlen(str);
permute(str, 0, n-1);
return 0;
}
If the recursion becomes too deep, there is a risk of stack overflow. So how could we avoid that with this style of recursive functions (if possible, without drastically modifying the algorithm)?
This does not produce the exact same output, but is an iterative way of printing all permutations of a string. Adapted from cppreference.com.
void reverse(char *a, int l, int r)
{
while ((l != r) && (l != --r)) {
swap(a+(l++), a+r);
}
}
bool next_permutation(char *a, int l, int r)
{
if (l == r) return false;
int i = r;
if (l == --i) return false;
while (true) {
int i1 = i;
if (a[--i] < a[i1]) {
int i2 = r;
while (!(a[i] < a[--i2]))
;
swap(a+i, a+i2);
reverse(a, i1, r);
return true;
}
if (i == l) {
reverse(a, l, r);
return false;
}
}
}
void permute(char *a, int l, int r)
{
do {
printf("%s\n", a);
} while(next_permutation(a, l, r+1));
}
Demo
I am learning backtracking and recursion and I am stuck at an algorithm for printing all the permutations of a string. I solved it using the bell algorithm for permutation but I am not able to understand the recursion method. I searched the web and found this code:
void permute(char *a, int i, int n)
{
int j;
if (i == n)
printf("%s\n", a);
else
{
for (j = i; j <= n; j++)
{
swap((a+i), (a+j));
permute(a, i+1, n);
swap((a+i), (a+j));
}
}
}
How is this algorithm basically working I am unable to understand? I even tried dry running!
How is the backtracking applied?
And is it more efficient than the Bell Algorithm for calculation of permutation?
The algorithm basically works on this logic:
All permutations of a string X is the same thing as all permutations of each possible character in X, combined with all permutations of the string X without that letter in it.
That is to say, all permutations of "abcd" are
"a" concatenated with all permutations of "bcd"
"b" concatenated with all permutations of "acd"
"c" concatenated with all permutations of "bad"
"d" concatenated with all permutations of "bca"
This algorithm in particular instead of performing recursion on substrings, performs the recursion in place on the input string, using up no additional memory for allocating substrings. The "backtracking" undoes the changes to the string, leaving it in its original state.
The code has 2 problems, both related to n, the assumed length of the string. The code for (j = i; j <= n; j++) { swap((a+i), (a+j)); ... swap in string's null character '\0' and gives code truncated results. Check the original (i == n) which should be (i == (n-1)).
Backtracking is applied by calling swap() twice effective undoing its original swap.
The order of complexity is the same for Bell Algorithm.
#include <stdio.h>
void swap(char *a, char *b) { char t = *a; *a = *b; *b = t; }
void permute(char *a, int i, int n) {
// If we are at the last letter, print it
if (i == (n-1)) printf("%s\n", a);
else {
// Show all the permutations with the first i-1 letters fixed and
// swapping the i'th letter for each of the remaining ones.
for (int j = i; j < n; j++) {
swap((a+i), (a+j));
permute(a, i+1, n);
swap((a+i), (a+j));
}
}
}
char s[100];
strcpy(s, "ABCD");
permute(s, 0, strlen(s));
The code that you found is correct! The algorithm swaps the current character in the string with all the subsequent characters and recursively calling the function. Its difficult to explain in words. The figure below may be of some help to you.
Backracking is being done in the 2nd swap for reversing the effect of the 1st swap i.e. we are going back to the original string and will now swap the next character in the array with the current character. The time complexity of the algo. is O(n*n!) since the loop runs n times and the permute function is called n! times. (For the 1st iteration, its called n times; for 2nd iteration (n-1) times and so on).
Source: http://www.geeksforgeeks.org/write-a-c-program-to-print-all-permutations-of-a-given-string/
Recursion really simplifies it:
public static void permutation(String str)
{
permutation("", str);
}
private static void permutation(String prefix, String str)
{
int n = str.length();
if (n == 0) {
System.out.println(prefix);
} else {
for (int i = 0; i < n; i++)
permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n));
}
}
Pseudo code:
String permute(String a[])
{
if (a[].length == 1)
return a[];
for (i = 0, i < a[].length(); i++)
append(a[i], permute(a[].remove(i)));
}
I create more specific but not efficient Program for permutation for general string.
It's work nice way.
//ubuntu 13.10 and g++ compiler but it's works on any platform and OS
//All Permutation of general string.
#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>
using namespace std;
int len;
string str;
void permutation(int cnum)
{
int mid;
int flag=1;
int giga=0;
int dead=0;
int array[50];
for(int i=0;i<len-1;i++)
{
array[50]='\0';
dead=0;
for(int j=cnum;j<len+cnum;j++)
{
mid=j%len;
if(mid==cnum && flag==1)
{
cout<<str[mid];
array[dead]=mid;
dead++;
flag=0;
}
else
{
giga=(i+j)%len;
for(int k=0;k<dead;k++)
{
if((array[k]==giga) && flag==0)
{
giga=(giga+1)%len;
}
}
cout<<str[giga];
array[dead]=giga;
dead++;
}
}
cout<<endl;
flag=1;
}
}
int main()
{
cout<<"Enter the string :: ";
getline(cin,str);
len=str.length();
cout<<"String length = "<<len<<endl;
cout<<"Total permutation = "<<len*(len-1)<<endl;
for(int j=0;j<len;j++)
{
permutation(j);
}
return 0;
}
# include <stdio.h>
/* Function to swap values at two pointers */
void swap (char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
/* Function to print permutations of 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++)
{
swap((a+i), (a+j));
permute(a, i+1, n);
swap((a+i), (a+j)); //backtrack
}
}
}
/* Driver program to test above functions */
int main()
{
char a[] = "ABC";
permute(a, 0, 2);
getchar();
return 0;
}
def perms(s):
if len(s) < 1:
return [s]
ps = []
for i in range(0, len(s)):
head, tail = s[i], s[0:i] + s[i + 1:]
ps.extend([head + tailp for tailp in perms(tail)])
return ps
I'm trying to generate permutations of a string and store them in a pointer array
#include<stdio.h>
#include<string.h>
int count;
char *str[100];
/* Function to swap values at two pointers */
void swap (char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
/* Function to print permutations of 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)
{
str[count++]=a;
printf("%s\n", str[count-1]);
}
else
{
for (j = i; j <= n; j++)
{
swap((a+i), (a+j));
permute(a, i+1, n);
swap((a+i), (a+j)); //backtrack
}
}
}
/* Driver program to test above functions */
int main()
{
char a[] = "ABC";
int i;
count=0;
permute(a, 0, 2);
for(i=0;i<count;i++)
printf("%s\n", str[i]);
return 0;
}
When I execute this, I get output as:
ABC ACB BAC BCA CBA CAB
ABC ABC ABC ABC ABC ABC
Why am i getting these different values for str in different functions?
Solved:
str[count++]=strdup(a);
or
converted *str[] to str[][] and then did strcpy(str[],a)
You are editing 'a' in place. You should make a copy of each resulting permutation.
str[count++]=strdup(a);
The code given below prints all the possible combination of a given string. It produces strings recursively . Now i want to store each combination in an array using an array of pointer to each string . How do i initialize the pointer so that it points to string.
The code is :-
Input ABC
Output
ABC in b[0]
ACB in b[1]
BAC
BCA
CAB
CBA
and so on .
thanks :)
void permute(char *a, int i, int n)
{
int k=0;
char *b[100];
int j;
if (i == n)
{
// *b[k]=a;
printf("%s\n", a);
i++;
}
else
{
for (j = i; j <= n; j++)
{
swap((a+i), (a+j));
permute(a, i+1, n);
swap((a+i), (a+j)); //backtrack
}
}
}
There is no point in pointing elements of b to a, since is a variable string (that is, it keeps changing). Possible output of such code would be that all elements of b would be last permutation of the string a.
You need dynamic allocation of string each time you find a new permutation.
That you can do manually using malloc(). Or can use strdup() to create duplicate strings for you (Remember to free() them at the end ofcourse).
/*Sample Code*/
if (i == n)
{
b[k] = strdup(a);
...
}
Remember, that you also need to pass k as the argument to the function permute(), since k is an automatic variable, newly created with value = 0, each time function permute() is called. There are other possibilities, make k global or static variable.
You could dynamically allocate an array that would hold individual char arrays (or C strings) representing each permutation. One of the things that would make this code generic is to find the value of total_permutations in the main() for a given string with strlen N, which would actually be factorial(N). Here:
void swap(char* A, char* B) {
char t;
t = *A;
*A = *B;
*B = t;
}
int permute(char **arr_of_chars, int count, char *a, int i, int n)
{
int k=0;
char *b[100];
int j;
if (i == n) {
// *b[k]=a;
printf("%s\n", a);
memcpy(arr_of_chars[count], a, strlen(a));
count++;
i++;
} else {
for (j = i; j <= n; j++) {
swap((a+i), (a+j));
count = permute(arr_of_chars, count, a, i+1, n);
swap((a+i), (a+j)); //backtrack
}
}
return count;
}
int main() {
char str[] = "";
char **arr_of_str = NULL;
int len_str = strlen(str);
int i = len_str;
int total_permutations = 1;
while (i > 0) { /* Get all the combinations */
total_permutations *= i;
i--;
}
arr_of_str = (char **) malloc(total_permutations * sizeof(char*));
for (i=0; i <total_permutations; i++) {
arr_of_str[i] = (char *) malloc(sizeof(char) * len_str);
}
permute(arr_of_str, 0, str, 0, (len_str-1));
for (i=0; i <total_permutations; i++) {
printf("%s \n", arr_of_str[i]);
free(arr_of_str[i]);
}
free(arr_of_str);
}