使用具有2个列表

时间:2017-05-03 12:52:27

标签: java recursion

我目前正在研究一个问题,以获得2个列表的所有排列。

问题: 我们有3个足球比赛,3个球场,使用重复功能,找到可以分配球场的所有可能的排列。

匹配{“a”,“b”,“c”},投球{1,2,3}。

结果将是一组具有match =>音高分配的HashMaps。

{{“a”=> 1,“b”=> 2,“c”=> 3},{“a”=> 1,“c”=> 2,“b” => 3},{“b”=> 1,“a”=> 2,“c”=> 3},{“b”=> 1,“c”=> 2,“ a“=> 3},{”c“=> 1,”a“=> 2,”b“=> 3},{”c“=> 1,”b“=> 2 ,“a”=> 3}}

任何指向类似问题,建议或伪代码的链接都会有所帮助。

我以不同的方式完成了这项工作,其中我得到了所有不同的音高序列,然后迭代这些结果并分配匹配a,b,c。代码如下。但我觉得可以有更好的解决方案。

public static void allocate(ArrayList<Match> matches, ArrayList<Pitch> pitches){

    Set<Map<Match, Pitch>> set = new HashSet<Map<Match, Pitch>>();

    // list is the return object
    ArrayList<ArrayList<Pitch>> list = new ArrayList<ArrayList<Pitch>>();

    // call the recursive function to populate the list object
    list = (ArrayList<ArrayList<Pitch>>) pitchPermutations(new ArrayList<Pitch>(), pitches, list, matches.size());

    // iterate through all the possible combinations of pitches add the matches
    for(ArrayList<Pitch> vs : list){
        if(vs.size() != matches.size()) continue;

        HashMap<Match,Pitch> m = new HashMap<Match,Pitch>();

        for(int i = 0; i < vs.size(); i++){
            Match e = matches.get(i);
            Pitch v = vs.get(i);
            m.put(e, v);
        }
        set.add(m);
    }

    // print the information
    int count = 1;
    for (Map<Match, Pitch> m : set ){
        System.out.println("----- "+count+" ------");
        for (Map.Entry<Match, Pitch> entry : m.entrySet()) {
            System.out.println("Match :  " + entry.getKey().getName());
            System.out.println("Pitch :  " + entry.getValue().getName());
        }
        count++;
    }

    // return set;

}

private static ArrayList<ArrayList<Pitch>> pitchPermutations(ArrayList<Pitch> pitches, ArrayList<Pitch> pitchesList, ArrayList<ArrayList<Pitch>> returnList, int length){
    // variable to hold the amount of pitches available
    int n = pitchesList.size();

    // if the pitches equals the number of pitches needed, add this list to the returnList variable
    if(pitches.size() == length){
        returnList.add(pitches);
        return returnList;
    }else{

        // 
        for( int i = 0 ; i < pitchesList.size(); i++){
            // remove the item which is added to the pitches to be passed recursively
            ArrayList <Pitch> p = new ArrayList<Pitch>(pitchesList.subList(0,i));
            p.addAll(new ArrayList<Pitch>(pitchesList.subList(i+1, n)));

            ArrayList<Pitch> pitches1 = (ArrayList<Pitch>) pitches.clone();
            pitches1.add(pitchesList.get(i));

            returnList = pitchPermutations(pitches1, p, returnList, length );
        }

    }
    return returnList;
}

1 个答案:

答案 0 :(得分:0)

你让这有点过于复杂。

  1. 在排列过程之外将音高保持为常数。只需传入匹配列表并接收排列列表即可。然后简单地遍历该列表,按顺序分配音高。
  2. 递归排列过程是众所周知的:
    1. 列表中的每个元素 N
      1. 重复列表的其余部分;
      2. 获取返回的排列列表;将 N 附加到该列表的每个元素。
      3. 将这些新排列(添加了 N )附加到此调用的结果列表中。
    2. 将结果列表返回给调用实例。
  3. 这会让你感动吗?如果您在线搜索,您可能会发现Java排列代码已准备好适应您的目的。