N个列表的排列 [英] Permutation of N lists
问题描述
我需要N个列表中的所有置换,直到程序启动我才知道N,这是我的SSCCE(我已经实现了建议给我的算法,但是它有一些错误).
i need all permutation from N lists, i dont know N until the program start, here is my SSCCE (i have implemented algorithm which was adviced to me, but it has some bugs).
首先,创建Place类:
First , create Place class:
public class Place {
public List<Integer> tokens ;
//constructor
public Place() {
this.tokens = new ArrayList<Integer>();
}
}
然后测试课程:
public class TestyParmutace {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
List<Place> places = new ArrayList<Place>();
Place place1 = new Place();
place1.tokens.add(1);
place1.tokens.add(2);
place1.tokens.add(3);
places.add(place1); //add place to the list
Place place2 = new Place();
place2.tokens.add(3);
place2.tokens.add(4);
place2.tokens.add(5);
places.add(place2); //add place to the list
Place place3 = new Place();
place3.tokens.add(6);
place3.tokens.add(7);
place3.tokens.add(8);
places.add(place3); //add place to the list
//so we have
//P1 = {1,2,3}
//P2 = {3,4,5}
//P3 = {6,7,8}
List<Integer> tokens = new ArrayList<Integer>();
Func(places,0,tokens);
}
/**
*
* @param places list of places
* @param index index of current place
* @param tokens list of tokens
* @return true if we passed guard, false if we did not
*/
public static boolean Func( List<Place> places, int index, List<Integer> tokens)
{
if (index >= places.size())
{
// if control reaches here, it means that we've recursed through a particular combination
// ( consisting of exactly 1 token from each place ), and there are no more "places" left
String outputTokens = "";
for (int i = 0; i< tokens.size(); i++) {
outputTokens+= tokens.get(i) +",";
}
System.out.println("Tokens: "+outputTokens);
if (tokens.get(0) == 4 && tokens.get(1) == 5 && tokens.get(2) == 10) {
System.out.println("we passed the guard with 3,5,8");
return true;
}
else {
tokens.remove(tokens.get(tokens.size()-1));
return false;
}
}
Place p = places.get(index);
for (int i = 0; i< p.tokens.size(); i++)
{
tokens.add(p.tokens.get(i));
//System.out.println("Pridali sme token:" + p.tokens.get(i));
if ( Func( places, index+1, tokens ) ) return true;
}
if (tokens.size()>0)
tokens.remove(tokens.get(0));
return false;
}
}
这是此代码的输出:
Tokens: 1,3,6,
Tokens: 1,3,7,
Tokens: 1,3,8,
Tokens: 3,4,6,
Tokens: 3,4,7,
Tokens: 3,4,8,
Tokens: 4,5,6,
Tokens: 4,5,7,
Tokens: 4,5,8,
Tokens: 2,3,6,
Tokens: 2,3,7,
Tokens: 2,3,8,
Tokens: 3,4,6,
Tokens: 3,4,7,
Tokens: 3,4,8,
Tokens: 4,5,6,
Tokens: 4,5,7,
Tokens: 4,5,8,
Tokens: 3,3,6,
Tokens: 3,3,7,
Tokens: 3,3,8,
Tokens: 3,4,6,
Tokens: 3,4,7,
Tokens: 3,4,8,
Tokens: 4,5,6,
Tokens: 4,5,7,
Tokens: 4,5,8,
因此,您看到,有些组合是正确的(1,3,6),有些组合是不正确的(4,5,8),而有些组合则是完全缺失的(2,4,8,..)如何解决此问题?位置的数量以及令牌的数量可能会有所不同,我只使用了3个位置,因为有2个位置可以工作,但有更多的位置却是越野车. 谢谢.
So, you see, some combinations are correct (1,3,6), some are incorrect (4,5,8) and some are completely missing (2,4,8,..) how to solve this problem ? number of places and also number of tokens in places can vary, i just used 3 places since with 2 places its working, but with more places it is buggy. Thanks.
推荐答案
您的算法几乎是正确的.我认为您在获得true
时不需要返回true
或false
并停止当前迭代.我修改了您的方法Func
:
You algorithm is almost correct. I think you don't need to return true
or false
and stop current iteration when you get true
. I modified your method Func
:
public static void Func( List<Place> places, int index, Deque<Integer> tokens) {
if (index == places.size()) {
// if control reaches here, it means that we've recursed through a particular combination
// ( consisting of exactly 1 token from each place ), and there are no more "places" left
String outputTokens = "";
for (int token : tokens) {
outputTokens += token + ",";
}
System.out.println("Tokens: "+outputTokens);
} else {
Place p = places.get(index);
for (int token : p.tokens) {
tokens.addLast(token);
Func(places, index+1, tokens);
token.removeLast();
}
}
}
我使用了 Deque ,因为它提供了方便的removeLast
方法来删除最后添加的令牌.您可以将LinkedList
作为Deque
的实现传递.
I used Deque because it offers handy removeLast
method to remove last added token. You can pass LinkedList
as implementation of Deque
.
更新
List<List<Integer>> combinations;
// Instead of printing result:
List<Integer> copy = new ArrayList<Integer>(tokens);
combinations.add(copy);
这篇关于N个列表的排列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!