字符串全排列
規則
最簡單的思路就是使用遞歸實現:
將最左邊字符固定,後面的依次全排
上一步的依次安排實際上是一次小集合的字符串全排
將次左邊字符固定,剩下的全排
將此次左邊固定…
直到最後一個數
第一輪結束,將原始字符串的最左邊字符與次左邊字符交換位置
按照上面的順序依次進行
將原始字符串從左數第3位固定到最左邊
依次進行
…直到左右進行完畢輸出
實例
舉例來講:原是字符串爲’abc’
a固定,剩下兩個準備全排
剩下的兩個中b固定,剩下的全排
只剩下一個字符,完成一次輸出
一次遞歸後返回上一步,將c固定
剩下b全排,輸出
a固定的雖有結果輸出完畢
將b或c固定到首位
按照上面順序進行全排
實現
#include <iostream>
#include <cstring>
using namespace std;
void callFunc(char * str,int from,int to){
if(to<=1)
return ;
if(from==to){
for(int i=0;i<strlen(str);i++)
cout<<str[i];
cout<<'\n';
}
else{
for(int i=from;i<to;i++){
swap(str[from],str[i]);
callFunc(str,from+1,to);
swap(str[i],str[from]);
}
}
}
int main()
{
char s[]={'a','b','c','d','\0'};
callFunc(s,0,strlen(s));
return 0;
}
上面要注意的是,char s[]={'a','b','c','d'}
,當使用strlen函數計算字符數組長度是總是輸出錯誤數值11,發現strlen函數使用的查詢’\0’字符數組,上面字符數組沒有字符串結尾字符,所以函數越界。或者可以直接使用string類型:
#include <iostream>
#include <cstring>
using namespace std;
void callFunc(string str,int from,int to){
if(to<=1)
return ;
if(from==to){
for(int i=0;i<3;i++)
cout<<str[i];
cout<<'\n';
}
else{
for(int i=from;i<to;i++){
swap(str[from],str[i]);
callFunc(str,from+1,to);
swap(str[i],str[from]);
}
}
}
int main()
{
string xxx ="abc";
cout<<xxx.size()<<endl;
callFunc(xxx,0,3);
return 0;
}
StringBuilder sb=new StringBuilder(str);
public String swap(String str,int x,int y){
char t=sb.charAt(x);
char v=sb.charAt(y);
sb.setCharAt(x, v);
sb.setCharAt(y, t);
return sb.toString() ;
}
public void strfunc(String str,int from ,int to){
if(from==to){
System.out.println(str);
return;
}
for(int i=from;i<to;i++){
str=swap(str, i, from);
strfunc(str, from+1, to);
str=swap(str, i, from);
}
}