public static void confusion(char[] str,int i){
if (i >= str.length)
return;
if (i == str.length - 1) {
System.out.println(String.valueOf(str));
} else {
for (int j = i; j < str.length; j++) {
char temp = str[j];
str[j] = str[i];
str[i] = temp;
confusion(str, i + 1);
temp = str[j];
str[j] = str[i];
str[i] = temp;
}
}
}
这个递归可以实现的功能:
输入:abcd
输出:abcd abdc acbd acdb ..... dcba
这是以交换递归的方式做字符串的全排列,从第一位起每位与后面位交换后遍历递归。
推荐非递归算法:由后向前找替换数和替换点,然后由后向前找第一个比替换数大的数与替换数交换,最后颠倒替换点后的所有数据。以下为一个C++实现。
#include<iostream> #include<algorithm> #include<cstring> using namespace std; #include<assert.h> //反转区间 void Reverse(char* pBegin , char* pEnd) { while(pBegin < pEnd) swap(*pBegin++ , *pEnd--); } //下一个排列 bool Next_permutation(char a[]) { assert(a); char *p , *q , *pFind; char *pEnd = a + strlen(a) - 1; if(a == pEnd) return false; p = pEnd; while(p != a) { q = p; p--; if(*p < *q) //找降序的相邻2数,前一个数即替换数 { //从后向前找比替换点大的第一个数 pFind = pEnd; while(*pFind < *p) --pFind; swap(*p , *pFind); //替换点后的数全部反转 Reverse(q , pEnd); return true; } } Reverse(a , pEnd); //如果没有下一个排列,全部反转后返回false return false; } int cmp(const void *a,const void *b) { return int(*(char *)a - *(char *)b); } int main(void) { char str[] = "bac"; int num = 1; qsort(str , strlen(str),sizeof(char),cmp); do { printf("第%d个排列\t%s\n",num++,str); }while(Next_permutation(str)); return 0; }
递归的牛逼之处就是用很简短的代码实现很复杂的功能。这也是很多程序猿觉得用递归实现一些功能会很牛逼。
@prison: 这个递归其实是有问题的。试想如果字符串中有重复的字符呢?