排列算法

下面是从一个关于排列算法的帖子中剪出来的。觉得算法比较简洁(运用递归)。

原题如下:用1、2、2、3、4、5这六个数字,用java写一个main函数,打印出所有不同的排列,如:512234、412345等,要求: "4 "不能在第三位, "3 "与 "5 "不能相连.
Author: JianZhiZG
//===========================
本来以为很简单,用递归一下就搞定的问题,结果按照递归的常规思路,在打印的时候碰到了很麻烦的问题,费了我不少脑筋,结果答案还是很简单,弄得我做出来 了过后都准备把结果放到博客商保存了。其实我做的是字符串排列显示的问题,其中打印时的条件判断语句是根据楼主的特殊要求添加的,诸位参考:
import   java.util.*;
public   class   test   {
public   static   void   main(String[]   arg)   {
Scanner   r=new   Scanner(System.in);
String   s=r.nextLine();
Pailie(s, " ");
}
static   void   Pailie(String   s,   String   p)   {
if(s.length() <1)   {
String   t=p+s;
if(t.charAt(2)!= '4 '   &&   t.contains( "35 ")==false)
System.out.println(t);
}
else   {
for(int   i=0;   i <s.length();   i++)   {
Pailie(s.substring(1),p+s.substring(0,1));
s=s.substring(1)+s.substring(0,1);
}
}
}
}
//=========================
对算法的最终改进,这次应该是比较完整的版本了吧。
思路是这样的,对于任意一个串利用递归进行排列时,我们是循环串中的每个字符到第一个字符进行递归。如果串中字符出现重复的话,则重复的字符只可以利用递 归算法一次,即只要与前面相同的字符循环到第一个字符时不调用递归就可以避免重复,为此,我们只需要按如下方式修改算法:
import   java.util.*;
public   class   test   {
static   int   count=0;
        public   static   void   main(String[]   arg)   {
                Scanner   r=new   Scanner(System.in);
                String   s=r.nextLine();
                Pailie(s, " ");
                System.out.println( "Total: "+count);
        }
        static   void   Pailie(String   s,String   p)   {
                if(s.length() <1)   {
                System.out.println(p);//字符串长度小于1,换行
                count++;
                }
                else   {
                int   index[]=new   int[s.length()];
                for(int   i=0;   i <s.length();   i++)//该循环将所有字符的第一次出现的位置记录在数组index中
                index[i]=s.indexOf(s.charAt(i));
                for(int   i=0;   i <s.length();   i++)   {
                if(i==index[i])//只有当循环数与第一次记录数相等时才递归,保证相同字符中的第一个调用
                Pailie(s.substring(1),p+s.substring(0,1));//递归,打印其它字符
                s=s.substring(1)+s.substring(0,1);//循环移位
                        }
                }
        }
}
这样,由于相同的字符只递归调用了一次,则避免了重复串的排列。下面是几个典型的运算结果:
2222222(输入。当串中的所有字符相同时,应该递归调用1次)
2222222
Total:1  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值