java实现全排列(有重复)
全排列(有重复)上一部分的全排列是无重复的,咱们遍历的条件就是想办法让每一个数字只选择一次,选择过了 ,咱们就不选,利用continue跳过,但是如果有重复数字在里面,我们恐怕就不能用数字是否重复来判断这个数字是否选择了,如果这样判断的话,我们数字会永远缺了重复的那个数字。整体思路:整体思路其实就是上一部分无重复的全排列思路非常像,我们开始利用的是数字不重复来选取需要的数字,那么我们现在可以通过序
全排列(有重复)
上一部分的全排列是无重复的,咱们遍历的条件就是想办法让每一个数字只选择一次,选择过了 ,咱们就不选,利用continue跳过,但是如果有重复数字在里面,我们恐怕就不能用数字是否重复来判断这个数字是否选择了,如果这样判断的话,我们数字会永远缺了重复的那个数字。
整体思路:
整体思路其实就是上一部分无重复的全排列思路非常像,我们开始利用的是数字不重复来选取需要的数字,那么我们现在可以通过序号是否取过,取过咱们就不要,也就是说,另外开取一个容器,来装取出数字的序号,然后判断这个序号是否取过了,如果取过了,咱们就退出
整个代码就是:
public class number{
static ArrayList <String> w = new ArrayList();
static List <Integer> M = Arrays.asList(1,2,3,5);
/*多出一个容器来装数字响应的序号*/
public static void run(ArrayList<Integer> selected,List<Integer> choose,ArrayList<Integer> to) {
if(selected.size() == choose.size()) {
w.add(Arrays.toString(selected.toArray()));
return;
}
for(int i=0;i<choose.size();i++) {
Integer num = choose.get(i);
Integer a = i;//用Integer来存放i
/*如果to里面已经有a了,那么说明这个数字已经选过,直接跳过*/
if(to.contains(a)) {
continue;
}
//与selected完全一样,to只是存储他们的序列而已
to.add(a);
selected.add(num);
run(selected,choose,to);
to.remove(a);
selected.remove(num);
}
}
public static void main(String[] args) {
ArrayList<Integer> selected = new ArrayList();
ArrayList<Integer> to = new ArrayList();
run(selected,M,to);
for(int i=0;i<w.size();i++) {
System.out.println(w.get(i));
}
}
}
代码整体一看,感觉似乎差不多的代码,只是多加了一个to容器来存储数字本该有的序列而已,用了另外一种形式来挑选数字,
数字不同时,也是另外一种判断方式,但是数字相同时,就会发现很多组数字都重复了,因为他们是按照序列来排序的,而不是看你数字来排序的,这个时候还需要再筛选一次
去除重复序列
去除重复序列只需要判断一下存储字符串的容器当中,有没有存储过这一个字符串,如果存过了,就跳过去,不存进去,java自配的容器,非常好使。这串代码只需要在判断return处加上就可以了。
if(selected.size() == choose.size()) {
if(w.contains(Arrays.toString(selected.toArray()))==false) {
w.add(Arrays.toString(selected.toArray()));
}
return;
}
这样就剔除了重复的字符串,但是如果想要更干净一点的代码,把两边的框框去掉,可以利用replaceAll把[ ]给换掉
最终代码:
public class number{
static ArrayList <String> w = new ArrayList();
static List <Integer> M = Arrays.asList(1,2,2,5);
public static void run(ArrayList<Integer> selected,List<Integer> choose,ArrayList<Integer> to) {
if(selected.size() == choose.size()) {
if(w.contains(Arrays.toString(selected.toArray()).replaceAll("\\[|\\]", ""))==false) {
w.add(Arrays.toString(selected.toArray()).replaceAll("\\[|\\]", ""));
}
return;
}
for(int i=0;i<choose.size();i++) {
Integer num = choose.get(i);
Integer a = i;
if(to.contains(a)) {
continue;
}
to.add(a);
selected.add(num);
run(selected,choose,to);
to.remove(a);
selected.remove(num);
}
}
public static void main(String[] args) {
ArrayList<Integer> selected = new ArrayList();
ArrayList<Integer> to = new ArrayList();
run(selected,M,to);
for(int i=0;i<w.size();i++) {
System.out.println(w.get(i));
}
}
}
很感谢提出问题的朋友,大概是参数selected出了问题,我重新修改了一下思路,利用to的序列,直接对应输出全排列即可,感兴趣的同学也可以研究一下,为啥selected会出现问题(我也挺迷惑的)
public class number{
static ArrayList <String> w = new ArrayList();
static ArrayList <String> m = new ArrayList();
static ArrayList <String> z = new ArrayList();
static List <Integer> M = Arrays.asList(1,2,2,5);
/*多出一个容器来装数字响应的序号*/
public static void run(ArrayList<Integer> selected,List<Integer> choose,ArrayList<Integer> to) {
/*if(selected.size() == choose.size()) {
w.add(Arrays.toString(selected.toArray()));
return;
}*/
if(to.size() == choose.size()) {//把[]去掉
ArrayList<Integer> temp = new ArrayList();
if(w.contains(Arrays.toString(to.toArray()).replaceAll("\\[|\\]", ""))==false) {
w.add(Arrays.toString(to.toArray()).replaceAll("\\[|\\]", ""));
//System.out.println(Arrays.toString(to.toArray()).replaceAll("\\[|\\]", ""));
//把to对应的序列转化成M中对应的符号
for(int i=0;i<to.size();i++) {
temp.add(M.get(to.get(i)));
}
m.add(Arrays.toString(temp.toArray()));
}
return ;
for(int i=0;i<choose.size();i++) {
Integer num = choose.get(i);
Integer a = i;//用Integer来存放i
/*如果to里面已经有a了,那么说明这个数字已经选过,直接跳过*/
if(to.contains(a)) {
continue;
}
//与selected完全一样,to只是存储他们的序列而已
to.add(a);
selected.add(num);
run(selected,choose,to);
to.remove(a);
selected.remove(num);
}
}
public static void main(String[] args) {
ArrayList<Integer> selected = new ArrayList();
ArrayList<Integer> to = new ArrayList();
run(selected,M,to);
for(int i=0;i<m.size();i++) {
//清除[]和重复序列
if(z.contains(m.get(i).replaceAll("\\[|\\]", ""))==false) {
z.add(m.get(i).replaceAll("\\[|\\]", ""));
}
}
for(int i=0;i<z.size();i++) {
System.out.println(z.get(i));
}
System.out.println(z.size());
}
}
这样应该就没啥大问题了,有问题还可以一起讨论哇!!!
更多推荐
所有评论(0)