在另一个列表中找到最接近的值

时间:2014-10-09 18:25:22

标签: java

如果问题不明确,请告诉我。我可以提供更多信息。我在ArrayList中有以下音符

ArrayList<String> notesList = new ArrayList<>();
notesList.add("A");    //0
notesList.add("A#");    //1
notesList.add("B");     //2
notesList.add("C");     //3
notesList.add("C#");    //4
notesList.add("D");     //5
notesList.add("D#");    //6
notesList.add("E");     //7
notesList.add("F");     //8
notesList.add("F#");    //9
notesList.add("G");     //10
notesList.add("G#");    //11

我有两个子列表,一个用于升序,一个用于降序。它们都包含notesList的一部分。

ArrayList<String> ascendList = new ArrayList<>();
ArrayList<String> descendList = new ArrayList<>();

前:

ascendList = C, D, E, F#, G        //indices in notesList = 3,5,7,9,10
descendList = A, C#, E, F, G, G#   // indices in notesList = 0,4,7,8,10,11

我需要通过升序列表生成模式,然后降序,反之亦然。 例如:

  

D,E(来自升序列表),E,C#(来自降序列表)C,D,E,F#

     

(Ascend),F,E,C#,A(Descend)

     

F E C#(Descend),D,E(Ascend)

这样做有条件。当我想在升序模式的末尾连接降序模式时,我需要找到等于或低于最后一个升序音符的下一个音符,但是在降序列表中。

例如:如果F#是其中一种升序类型的最后一个音符,则F应该是降序模式中的第一个音符。如果E是升序模式中的最后一个音符,则E是降序模式中的第一个音符,因为E在升序和降序中都存在。类似地,当我在下降模式结束时生成上升模式时,我需要找到等于或高于最后一个下降音符的下一个音符。

我无法弄清楚如何做到这一点。 我尝试过的一种方法是找到对应于notesList的升序和降序的索引,然后考虑映射,然后使用map.higherKeymap.lowerKey等方法。但无法继续,因为我无法真正映射它们。

2 个答案:

答案 0 :(得分:1)

enum Note {
    C, C_, D, D_, E, F, F_, G, G_, A, A_, B;

    public Note above() {
        return ordinal() != values().length - 1
                ? Note.values()[ordinal() + 1]
                : Note.values()[0];
    }

    public Note below() {
        return ordinal() > 0
                ? Note.values()[ordinal() - 1]
                : Note.values()[Note.values().length - 1];
    }
}

interface Scale {
    ListIterator<Note> joinAfter(Note note);
}

Scale ascending = new Scale() {
    List<Note> notes = asList(C, D, E, F_, G);

    @Override
    public ListIterator<Note> joinAfter(Note note) {
        return notes.listIterator(notes.contains(note)? notes.indexOf(note) : notes.indexOf(note.above()));
    }
};

Scale descending = new Scale() {
    List<Note> notes = asList(A, C_, E, F, G, G_);

    @Override
    public ListIterator<Note> joinAfter(Note note) {
        return notes.listIterator(notes.contains(note)? notes.indexOf(note) : notes.indexOf(note.below()));
    }
};

我建议添加你自己的Iterator包装器,它将在descendingScale中调用next的next(如果你不想因为某种原因在那里使用反向音符),更重要的是允许你无限循环遍历音阶。

如果这只是学校的校对,你最好坚持使用数字,不要乱用字符串列表,直到你需要打印出来。顺便说一句,这将是一个更好的选择。

答案 1 :(得分:0)

一种可能的方法。对于升序和降序,创建与notesList大小相同的Ints(或布尔)数组。值为1表示注释在列表中,值为0表示不是。基本上,您使用加入/降序结构来索引到noteList。类似的东西:

int index = 3;
if (1 == acending[index]) {
    note = noteList[index];
}

创建方法以在升序和降序列表中上下移动索引,以查找下一个有效(非零)条目。当您从升序切换到降序时,在降序列表中使用相同的索引。如果您使用的是有效的注释,则使用它,不是,请搜索下一个有效的注释。

可能有很多变化。您可以创建封装列表和移动方法的名为AscendingScale和DescendingScale的对象。