查找用户定义对象的ArrayLists的ArrayList的所有组合

时间:2015-03-11 19:45:51

标签: java arraylist nested-lists

我已经定义了一个类Note来表示一种播放某个音符的方法(字符串乐器上的字符串和音品的两个整数),以及一个具有所有ArrayList的类Chord那个和弦中的音符。

对于播放的每个音符,可能有多种方式播放该音符,因此我有一个Notes的ArrayList表示每种可能的方式。在一个和弦中可以有任意数量的音符,所以我有一个ArrayList的ArrayList。从这里我想创建一个和弦的ArrayList,每种方式都可以演奏和弦。

我已经定义了一个构造函数Chord(ArrayList<Note> notes)

例如: 注意A有3种播放方式,注意B 2种播放方式,我想要和弦:

[A1,B1],[A1,B2],[A2 B1],[A2 B2],[A3,B1],[A3,B2]。

我创建了一种方法,该方法在假设总是有3个音符播放的情况下工作,但无法思考如何将其扩展为未知数字

public static ArrayList<Chord> allPlayable(ArrayList<ArrayList<Note>> candidates)
{
    ArrayList<Chord> allPlayable = new ArrayList<>();

    for (int i = 0; i < candidates.get(0).size(); i++)
    {
        Note n0 = candidates.get(0).get(i);

        for (int j = 0; j < candidates.get(1).size(); j++)
        {
            Note n1 = candidates.get(1).get(j);

            for (int k = 0; k < candidates.get(2).size(); k++)
            {
                Note n2 = candidates.get(1).get(k);


                ArrayList<Note> chordNotes = new ArrayList<>();

                chordNotes.add(n0);
                chordNotes.add(n1);
                chordNotes.add(n2);

                allPlayable.add(new Chord(chordNotes));

            }
        }
    }

    return allPlayable;
}

2 个答案:

答案 0 :(得分:0)

建议我使用递归 - 每个for循环都是另一个递归调用,我想出了这个答案

public static ArrayList<Chord> allPlayable(ArrayList<ArrayList<Note>> candidates)
{
    //this will be the inner ArrayList we are on 
    ArrayList<Note> current = new ArrayList();

    //the list of chords to return
    ArrayList<Chord> allPlayable = new ArrayList();

    allPlayableRecurse(candidates, 0, current, allPlayable);

    return allPlayable;
}
public static void allPlayableRecurse(ArrayList<ArrayList<Note>> candidates, int index, ArrayList<Note> chordNotes, ArrayList<Chord> allPlayable)
{
    ArrayList<Note> current = candidates.get(index);

    //for each note in the current array list of notes
    for (int i = 0; i < current.size(); i++)
    {
        chordNotes.add(current.get(i));

        //there are more notes to add
        if (index < candidates.size()-1)
        {
            //go to the next inner ArrayList
            allPlayableRecurse(candidates, index+1, chordNotes, allPlayable);
        }
        else//we have reached the last note
        {
            //add the chord to the list
            allPlayable.add(new Chord((ArrayList<Note>)chordNotes.clone()));
        }

        //we will now replace this note
        chordNotes.remove(chordNotes.size()-1);
    }
}

答案 1 :(得分:0)

您可以使用递归,例如:

   List<List<Note>> combine(List<List<Note>> representations) {
        List<Note> options = representations.get(0);
        List<List<Note>> tails;
        if (representations.size()==1) {
            tails = new ArrayList<>();
            tails.add(Collections.emptyList());
        } else {
            tails = combine(representations.subList(1, representations.size()));
        }

        List<List<Note>> combinations = new ArrayList<>(options.size());
        for (Note note : options) {
            for (List<Note> tail : tails) {
                List<Note> chord = new ArrayList<>();
                chord.add(note);
                chord.addAll(tail);
                combinations.add(chord);
            }

        }
        return combinations;

    }

    public List<Chord> allPlayable(List<List<Note>> candidates) {

        List<List<Note>> combinations = combine(candidates);
        List<Chord> chords = new ArrayList<>(combinations.size());
        for (List<Note> notes : combinations) chords.add(new Chord(notes));
        return chords;      

}

这是旧的java7风格。使用新的Java8功能操作可以更轻松地完成它,但如果刚刚开始,则不确定它是否已经是您的事情。