Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Print all the permutations of a string in C

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?

like image 613
poorvank Avatar asked Jun 07 '13 17:06

poorvank


3 Answers

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.

like image 118
bengoesboom Avatar answered Oct 23 '22 11:10

bengoesboom


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));
like image 31
chux - Reinstate Monica Avatar answered Oct 23 '22 11:10

chux - Reinstate Monica


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).

Recursion tree for permutations of string "ABC"

Source: http://www.geeksforgeeks.org/write-a-c-program-to-print-all-permutations-of-a-given-string/

like image 35
Shubham Mittal Avatar answered Oct 23 '22 10:10

Shubham Mittal