943,946 Members | Top Members by Rank

Ad:
  • C Code Snippet
  • Views: 7603
  • C RSS
2

Permutations of String using recursion

by on Sep 6th, 2005
This program was written and tested in unix/linux environment (in EMacs editor )with a GCC compiler.
C Code Snippet (Toggle Plain Text)
  1. /* This program was written using Emacs editor and tested using gcc compiler in Unix environment for other environments and other compilers than GCC you might have to make slight modifications */
  2.  
  3. /* The author of this program is Raghu.R, currently pursuing Masters at USC */
  4.  
  5. /* ------------------------------------------Note--------------------------------*/
  6. /* I have not followed the best of the programming practices, for eg I have used goto at a place or two, even though I could have done it using while or for, its just my fancy to use goto rather than those two, I had used goto and I have used bubble sort to sort the string, again I could have used merge or quick but since the string size is usally of smaller order I didnt use better sorting algorithms */
  7.  
  8. /* Any feedbacks and comments are welcome, I can be reached at rramaswa@usc.edu */
  9.  
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13. #include <assert.h>
  14. #include <unistd.h>
  15.  
  16. void BubbleSort(char *str, int array_size);
  17. void Print_Stack(char *stack,int length,char *str);
  18. void Permute(char str[],int level,int length,int index,char stack[],int cell);
  19. int Find_InStack(char value,char *stack,int len);
  20. int Check_InVector(int level,int length);
  21.  
  22. //int **hash_table;
  23. int *levels_vector;
  24.  
  25. int main(void)
  26. {
  27. char *str;
  28. //int *hash_table;
  29. int length;
  30. int index = -1;
  31.  
  32. int i = 0;
  33. int j = 0;
  34.  
  35. char *stack;
  36. int spl_flag;
  37.  
  38. spl_flag = 0;
  39.  
  40. /* This is the worst part of the algo, I am assuming the string size is no more than 1000, because there is no way before hand I can know the size of the string before hand of course I can allocate smaller size of array monitor for return key trap the return signal and reallocate but I didnt want to do all that crap :) */
  41. /* -----------------------------------Note---------------------------------------------*/
  42. /* for sizes above 100 itself it would take ages to compute the different permutations, if you want to test for sizes for 1000, change the value in malloc and use parallel supercomputers to get instant results :) */
  43.  
  44. str = (char *)malloc(1000 * sizeof(char));
  45. printf("Enter the String ..\n");
  46. gets(str);
  47. length = strlen(str);
  48.  
  49. str[length] = '\0';
  50.  
  51. /* sort the input string */
  52. BubbleSort(str,length);
  53. printf("Sorted String ..\n");
  54. puts(str);
  55.  
  56. /* Start computing permutations */
  57. printf("\n\nPrinting permutations .. \n\n");
  58.  
  59. /* If the string is of length 1 it is a special case */
  60. if(length == 1)
  61. {
  62. printf("[%d] ",1);
  63. puts(str);
  64. goto B;
  65. }
  66.  
  67. /* Allocate memory for a vector (a array initialized to zero)*/
  68. /* This would store the current index at each level (level in the tree) */
  69. levels_vector = (int *)malloc(length * sizeof(int ));
  70. assert(levels_vector);
  71.  
  72. /* Initialisze the levels_vector */
  73.  
  74. for(i = 0;i < length;i++)
  75. {
  76. levels_vector[i] = i;
  77. }
  78.  
  79. /* Call the permutation function for each level 1(ie beginning each character of the string )*/
  80. for(i = 0;i < length;i++)
  81. {
  82. /* Allocate memory for stack */
  83. /* Stack would contain the string permuted */
  84. stack = (char *)malloc(length *sizeof(int));
  85. assert(stack);
  86.  
  87. /* level 1 assigned to various characters in the string based on iterations*/
  88. levels_vector[0] = i;
  89. Permute(str,0,length,index,stack,i);
  90. free(stack);
  91. }
  92.  
  93. B: return 1;
  94.  
  95. }
  96.  
  97. /* This function computes the different permutations of the given string */
  98. void Permute(char str[],int level,int length,int index,char stack[],int cell)
  99. {
  100. int i = 0;
  101. int j = 0;
  102. int k = 0;
  103. level++;
  104. //printf(" Level %d ",level);
  105.  
  106. /* Return at level-2 the reason why I am doing this is at level 02 in the recursion tree it is obvious that the string would have to permute between the rest of remaining charaters for eg if the string in the stack is abd the remaining chracters would be c and e (assuming input string is abcde), so the obvious permutations would be abdce and abdec, I could have filled the stack going onto level = length but I thought it is obvious and would save recursion steps */
  107.  
  108. if(level > length - 2)
  109. {
  110. Print_Stack(stack,length,str);
  111. return;
  112. }
  113.  
  114. if(level == 1)
  115. {
  116. /* If the level is 1 it would be a special case */
  117. stack[level-1] = str[levels_vector[level-1]];
  118. }
  119. else
  120. {
  121. levels_vector[level-1] = Check_InVector(level,length);
  122. stack[level-1] = str[levels_vector[level-1]];
  123. }
  124.  
  125. /* This recursion would branch the left subtree */
  126. Permute(str,level,length,index,stack,cell);
  127. for(i = level;i < length-1;i++)
  128. {
  129. /* This recursion would branch the rite subtree */
  130. Permute(str,level,length,index,stack,cell);
  131. //printf("\n");
  132. }
  133. }
  134.  
  135. /* This function returns the index of the character to be selected from the input string based on the current level after checking the levels_vector array */
  136.  
  137. int Check_InVector(int level,int length)
  138. {
  139. int i = 0;
  140. int value = 0;
  141.  
  142. /* This is a important step, for each current level other than level do the following for all the levels above it check if the current character is already set in levels_vector, if already present skip and select the next character */
  143.  
  144. value = levels_vector[level-1];
  145.  
  146. A: value = value % length;
  147.  
  148. for(i = 0;i < level;i++)
  149. {
  150. /* If the current value is already present in the levels above it, this level cannot select the index to that character, increment and branch to label A */
  151. if(levels_vector[i] == value)
  152. {
  153. value++;
  154. goto A;
  155. }
  156. }
  157. return value;
  158. }
  159.  
  160. /* This function prints the contents in the stack */
  161. void Print_Stack(char *stack,int length,char *str)
  162. {
  163. int i = 0;
  164. char c1,c2;
  165. int char_count = 0;
  166. static int flag = 0;
  167. static int count = 0;
  168. //printf("\n Printing the stack now ..\n");
  169. //printf(" %d : ",count+1);
  170.  
  171. /*--------------------------------------------------------------------------*/
  172. /* This part is specifically for the part I mentioned earlier about
  173.   skipping 2 levels of recursion, the following part of the code detects the 2 characters missing from the stack that have to be included to finish the permutation */
  174.  
  175. for(i = 0;i < length;i++)
  176. {
  177. if(Find_InStack(str[i],stack,length-2) == 0)
  178. {
  179. if(char_count == 0)
  180. {
  181. c1 = str[i];
  182. char_count++;
  183. }
  184. else
  185. {
  186. c2 = str[i];
  187. }
  188. }
  189. }
  190. if(flag == 0)
  191. {
  192. stack[length-2] = c1;
  193. stack[length-1] = c2;
  194. flag++;
  195. }
  196. else
  197. {
  198. stack[length-2] = c2;
  199. stack[length-1] = c1;
  200. flag = 0;
  201. }
  202.  
  203. /*----------------------------------------------------------------------*/
  204.  
  205. printf("[%d] ",count+1);
  206.  
  207. /* Print the contents in the stack */
  208. for(i = 0;i < length;i++)
  209. {
  210. printf(" %c ",stack[i]);
  211. }
  212. count++;
  213. printf("\n");
  214. }
  215.  
  216. /* This function checks if the given character is in the stack */
  217. int Find_InStack(char value,char *stack,int len)
  218. {
  219. int i = 0;
  220. for(i = 0;i < len;i++)
  221. {
  222. if(stack[i] == value)
  223. return 1;
  224. }
  225. return 0;
  226. }
  227.  
  228.  
  229. /* This function bubble sorts the input string */
  230. void BubbleSort(char *str, int array_size)
  231. {
  232. int i, j;
  233. char temp;
  234.  
  235. for (i = (array_size - 1); i >= 0; i--)
  236. {
  237. for (j = 1; j <= i; j++)
  238. {
  239. if (str[j-1] > str[j])
  240. {
  241. temp = str[j-1];
  242. str[j-1] = str[j];
  243. str[j] = temp;
  244. }
  245. }
  246. }
  247. }
Comments on this Code Snippet
Aug 5th, 2006
0

Re: Permutations of String using recursion

Very confusing, very non standard .
A better implementation should have been pursued.
Failure as a human
~s.o.s~ is offline Offline
8,871 posts
since Jun 2006
Nov 16th, 2009
-1

Re: Permutations of String using recursion

please give a simple program to find permutation of a string using recursion
Newbie Poster
shameemah is offline Offline
1 posts
since Nov 2009
Nov 29th, 2009
0

Re: Permutations of String using recursion

Why the use of goto?
Newbie Poster
Minotauraus is offline Offline
1 posts
since Nov 2009
Nov 29th, 2009
0

Re: Permutations of String using recursion

Here are just a few suggestions:

line 46: >> gets(str);
Never ever use gets(). What will happen if I enter more characters than the buffer can hold? Answer: Seg Fault. Use fgets() instead because it will limit the input to the max length you want.

line 49: has no value because the string is already NULL terminated.

line 64: Delete that goto statement -- there are a lot of better ways to do that. goto is considered very bad programming practice.

lines 44 and 69: delete the typecase. C language does not require a typecase for functions such as malloc() which return void *.

line 84: There is no need to allocate stack on every iteration of that loop and may fragment memory! That's just grossly inefficient. Allocate it once before the loop starts then free it once after the loop ends.
Retired and Enjoying Life
Ancient Dragon is offline Offline
21,953 posts
since Aug 2005
Message:
Previous Thread in C Forum Timeline: Small problem with structures
Next Thread in C Forum Timeline: Using Linked List to write to a file





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC