求字符串的全排列

 
//求字符串的全排列
02 #include<iostream>
03 #include<algorithm>
04 #include<string>
05 using namespace std;
06 void print_arrange(string s){
07     sort(s.begin(),s.end());
08     do{
09         cout<<s<<endl;
10     }while(next_permutation(s.begin(),s.end()));
11 }
12 int _print_arrange(string s){
13      
14 }
15 int main(void){
16     string s;
17     cin>>s;
18     print_arrange(s);
19     return 0;
20 }
求一字符串的全排列(递归算法新写法)
2010-05-17 17:37

用C++写一个函数,打印出一个字符串的全排列,如输入字符串为abc,则打印出abc,acb,bac,bca,cab,cba

#include<iostream.h>

//左循环移位

void change(char str[],int len)

{

    if(len<2) return;

    char temp=str[0];

    for(int i=0;i<len;i++) str[i]=str[i+1];

    str[len-1]=temp;

}

void pai(char str[],int pos,int len)

{

    if(pos==len+1)

        cout<<index++<<":"<<str<<endl;

    else

    {

        for(int k=0;k<pos;k++)

        {

            pai(str,pos+1,len);

            change(str,pos);

        }

    }

}

void main()

{

    char [] str=”abcd”;

    pai(str,2,4);

}

算法思想:一个长度为len的字符串的全排列,可以这样求得,先对前len-1个字符串做全排列,然后再在这(len-1)!种排列的后面加上第len个字符,对每一种情况做len次循环移位,就得全部len*(len-1)!,即len!种全排列。

下图显示了整个递归的过程, pai函数展示了递归算法的一种新的写法:

一般的递归算法是由f(n)调用f(n-1),当参数为01时跳出递归,而上面的算法是由f(n-1)调用多个f(n),当参数为nn+1时,跳出递归。

记录一下,值得学习


 

 

问题: 比如是abcde,打印它的全排列,如果是任意字符串(考虑有重复字符串的情况)呢

 
 
Permutation( char a[], int start, int end) { int i; char temp; if (start == end) { for (i = 0 ; i <= end; i ++ ) printf( " %c " ,a[i]); printf( " \n " ); } else { for (i = start; i <= end; i ++ ) { temp = a[start]; a[start] = a[i]; a[i] = temp; Permutation(a, start + 1 , end); temp = a[start]; a[start] = a[i]; a[i] = temp; } } } int main() { char A[] = " abcc " ; Permutation(A, 0 , 3 ); getch(); return 0 ; }


 

 

 

算法程序题: 
    该公司笔试题就1个,要求在10分钟内作完。 
    题目如下:用1、2、2、3、4、5这六个数字,用java写一个main函数,打印出所有不同的排列,如:512234、412345等,要求:"4"不能在第三位,"3"与"5"不能相连。

 


  基本思路: 
1 把问题归结为图结构的遍历问题。实际上6个数字就是六个结点,把六个结点连接成无向连通图,对于每一个结点求这个图形的遍历路径,所有结点的遍历路径就是最后对这6个数字的排列组合结果集。 
2 显然这个结果集还未达到题目的要求。从以下几个方面考虑: 
  1. 3,5不能相连:实际要求这个连通图的结点3,5之间不能连通, 可在构造图结构时就满足改条件,然后再遍历图。 
  2. 不能有重复: 考虑到有两个2,明显会存在重复结果,可以把结果集放在TreeSet中过滤重复结果 
  3. 4不能在第三位: 仍旧在结果集中去除满足此条件的结果。

 

 


我采用二维数组定义图结构,最后的代码是:

 

 

 

 

Java代码    收藏代码
  1. import java.util.Iterator;  
  2. import java.util.TreeSet;  
  3. public class TestQuestion {  
  4. private String[] b = new String[]{"1""2""2""3""4""5"};  
  5. private int n = b.length;  
  6. private boolean[] visited = new boolean[n];  
  7. visited =falsh;  
  8. private int[][] a = new int[n][n];  
  9. private String result = "";  
  10. private TreeSet TreeSet = new TreeSet();  
  11. public static void main(String[] args) {  
  12. new TestQuestion().start();  
  13. }  
  14. private void start() {  
  15. for (int i = 0; i < n; i++) {  
  16. for (int j = 0; j < n; j++) {  
  17. if (i == j) {  
  18. a[i][j] = 0;  
  19. else {  
  20.     a[i][j] = 1;  
  21. }  
  22. }  
  23. }a[3][5] = 0;  
  24. a[5][3] = 0;  
  25. for (int i = 0; i < n; i++) {  
  26.     this.depthFirstSearch(i);  
  27. }  
  28. Iterator it = set.iterator();  
  29. while (it.hasNext()) {  
  30. String string = (String) it.next();  
  31.   
  32. if (string.indexOf("4") != 2) {  
  33. System.out.println(string);  
  34. }  
  35. }  
  36. }  
  37. private void depthFirstSearch(int startIndex) {  
  38. visited[startIndex] = true;  
  39. result = result + b[startIndex];  
  40. if (result.length() == n) {  
  41. TreeSet .add(result);  
  42. }  
  43. for(int j = 0; j < n; j++) {  
  44. if (a[startIndex][j] == 1 && visited[j] == false) {  
  45. depthFirstSearch(j);  
  46. else {  
  47. continue;  
  48. }  
  49. }  
  50.     result = result.substring(0, result.length() -1);  
  51.     visited[startIndex] = false;  
  52. }  
  53. }  

 

 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值