C實現字元排列,c實現字元
用已知字串s中的字元,產生由其中n個字元組成的所有字元的排列。設n小於字串s的字元個數,其中s中的字元在每個排列中最多出現一次。 例如,對於s[]=”abc”,n=2,則所有字元的排列有:ba,ca,ab,cb,ac,bc。
演算法思想:
使用遞迴完成該執行個體。
- 舉個例子:
- s = “abc”,n=2
- 則第一個perm(n,s),即perm(2,”abc”);
- 首先需要判斷w中的字元個數是否滿足,n=2>1,表示還沒有滿足
- 首先,從s的第一個元素開始,s[1] = ‘a’;
- 填充到w中,w[n-1]即,w[1] = ‘a’;
- 緊接著,進行一些調整,使得s1 = bc,n=1
- 進行同樣的perm,即perm(1,”bc”);同樣先進行判斷
- 選擇b填充到w中,在進入perm(0,”c”),判斷輸出
- 接著,回到上一層,perm(1,”bc”),再選擇字元”c”進入w
- 選擇c進入w之後,進行一些調整,將s1調整成這樣一個字串s1=”cb”,
- 這樣進入perm(0,”b”),判斷輸出.
*
- 接著,進入第一層,由於ba,ca都已經輸出完畢,第一個元素從b開始進行選擇
- 首先將b放入w中,即w[1] = ‘b’;接著進行一些調整,將s1調整為s1 = “bac”;
- 進入perm(1,”ac”);
- 以此方式進行遞迴,完成。
下面是代碼實現部分:
#include <stdio.h>#include <stdlib.h>#include <string.h>#define N 20char w[N];void perm(int n,char *s);/** * 用已知字串s中的字元,產生由其中n個字元組成的所有字元的排列。 * 設n小於字串s的字元個數,其中s中的字元在每個排列中最多出現一次。 * 例如,對於s[]="abc",n=2,則所有字元的排列有:ba,ca,ab,cb,ac,bc。 */int main(){ char s[N]; int n; printf("Please enter the char array:\n"); scanf("%s",&s); printf("Please number:\n"); scanf("%d",&n); perm(n,s); //調用排列函數 return 0;}/** * 舉個例子: * s = "abc",n=2 * 則第一個perm(n,s),即perm(2,"abc"); * 首先需要判斷w中的字元個數是否滿足,n=2>1,表示還沒有滿足 * 首先,從s的第一個元素開始,s[1] = 'a'; * 填充到w中,w[n-1]即,w[1] = 'a'; * 緊接著,進行一些調整,使得s1 = bc,n=1 * 進行同樣的perm,即perm(1,"bc");同樣先進行判斷 * 選擇b填充到w中,在進入perm(0,"c"),判斷輸出 * 接著,回到上一層,perm(1,"bc"),再選擇字元"c"進入w * 選擇c進入w之後,進行一些調整,將s1調整成這樣一個字串s1="cb", * 這樣進入perm(0,"b"),判斷輸出. * * 接著,進入第一層,由於ba,ca都已經輸出完畢,第一個元素從b開始進行選擇 * 首先將b放入w中,即w[1] = 'b';接著進行一些調整,將s1調整為s1 = "bac"; * 進入perm(1,"ac"); * 以此方式進行遞迴,完成。 */void perm(int n,char *s){ if(n < 1){ //如果n小於1,表示w中的長度已經達到需要的長度 printf("%s\n",w); return; }else{ char s1[N]; //臨時變數儲存 strcpy(s1,s); int i; for(i = 0;*(s1+i);i++){ //從s1中選擇一個字元放入w對應的位置中 *(w+n-1) = *(s1+i); //將從s1中被選擇的字元替換成第一個字元 *(s1+i) = *s1; //將第一個字元換成被選擇的字元 *s1 = *(w+n-1); perm(n-1,s1+1); } }}
下面是程式的運行結果:
總體來說,這個演算法的思路還是比較簡單的。