我有一个多维数组,用于包含问题和答案的 Java 测验应用程序(仅显示下面的代码片段)。
public static String[][][] question = {
{
//question bank 1 (index 0)
{"Question 1","Option 1","Option 2","Option 3","Option 4","Option 2"},
{"Question 2","Option 1","Option 2","Option 3","Option 4","Option 3"},
},
{
//question bank 2 (index 1)
{"Question 1","Option 1","Option 2","Option 3","Option 4","Option 4"},
}
};
每个数组中都有索引 0(问题)、索引 1-4(选项)、索引 5(答案)。
它调用问题[x][y][z],其中x表示问题库,y是问题数据,z是列。
在 2d 数组中,collections.shuffle 工作正常,但由于我将其扩展到 3d 数组,这不起作用,我不太知道我需要更改什么。
public void shuffleArray() {
List<String[][]> asList;
asList = Arrays.asList(question);
Collections.shuffle(asList);
question = asList.toArray(new String[0][0][0]);
}
它不是随机选择问题[0]数组或问题[1]数组内容,而是随机选择问题[0]数组内容。
理想情况下,我想随机化问题的顺序,以及能够随机化选项的显示顺序。至少对于第一部分,是否可以对collections.shuffle进行简单的调整,以适应3D数组?
将问题分解成更小的部分,并为每行银行的每一行创建一个对象,以便更好地控制洗牌方式。
-
在每个银行的每一行中随机排列选项
在每个 银行中随机排列每个银行(问题)的行
也洗牌银行?
请考虑以下示例:
原始数组在这里。
private static String[][][] questionBanks =
{
{
// bank 1
{ "Question 1", "Option 1", "Option 2", "Option 3", "Option 4", "Option 2" },
{ "Question 2", "Option 1", "Option 2", "Option 3", "Option 4", "Option 3" },
},
{
// question bank 2 (index 1)
{ "Question 1", "Option 1", "Option 2", "Option 3", "Option 4", "Option 4" },
}
};
main 方法,负责洗牌上面的数组,调用shuffle()
并打印结果以便您可以看到它。
public static void main(String... args) throws Exception {
shuffle();
print();
}
遍历题库数组并打印每个库的每一行。
private static void print() {
for (String[][] bank : questionBanks) {
System.out.println("==============");
for (String[] row : bank) {
System.out.println("------------");
for (String el : row) {
System.out.print(el);
System.out.print("t");
}
System.out.println("n");
}
}
}
此方法将通过将其分解为多个部分并使用处理随机选项并保留问题/答案的逻辑的对象QuestionBankRow
来洗牌数组。通过创建QuestionBankRow
对象,如果有一天必须重构以添加更多字段或更改逻辑,则可以更好地控制。如果可能,请考虑使用对象而不是String[][][]
数组来获取问题库。
private static void shuffle() {
List<String[][]> banks = new ArrayList<>();
for (String[][] bank : questionBanks) {
List<String[]> shuffledBankRows = new ArrayList<>();
for (String[] bankRow : bank) {
shuffledBankRows.add(new QuestionBankRow(bankRow).getShuffledBankRow());
}
Collections.shuffle(shuffledBankRows);
banks.add(shuffledBankRows.toArray(new String[0][0]));
}
// if you don't want to shuffle the banks around, don't perform
// this shuffle
Collections.shuffle(banks);
questionBanks = banks.toArray(new String[0][0][0]);
}
该类从题库中读取String[]
行,获取和随机播放选项。getShuffledBankRow()
方法返回一个String[]
,其中索引 0 作为问题,索引 1-4 作为随机选项,索引 5 作为答案。
private static class QuestionBankRow {
private static final int QUESTION_INDEX = 0;
private static final int OPTION_INDEX_START = 1;
private static final int OPTION_INDEX_END = 4;
private static final int ANSWER_INDEX = 5;
private static final int NUM_ELEMENTS_ROW = 6;
private final List<String> options;
private final String question;
private final String answer;
public QuestionBankRow(String[] rowArr) {
this.question = rowArr[QUESTION_INDEX];
this.answer = rowArr[ANSWER_INDEX];
this.options = new ArrayList<>();
for (int i = OPTION_INDEX_START; i <= OPTION_INDEX_END; i++) {
this.options.add(rowArr[i]);
}
}
public String[] getShuffledBankRow() {
List<String> shuffledOptions = new ArrayList<>(this.options);
Collections.shuffle(shuffledOptions);
String[] shuffledRow = new String[NUM_ELEMENTS_ROW];
shuffledRow[QUESTION_INDEX] = this.question;
for (int i = OPTION_INDEX_START; i <= OPTION_INDEX_END; i++) {
shuffledRow[i] = shuffledOptions.get(i - OPTION_INDEX_START);
}
shuffledRow[ANSWER_INDEX] = this.answer;
return shuffledRow;
}
}
问题是,List<String[][]>
不是3D数组。它是 2D 数组的列表。因此,当您执行Collections.shuffle(list)
时,您只会打乱 2D 数组的顺序,而不是它们的内容。
将列表想象成一所房子,将字符串 [][] 想象成它们的居民。有了Collections.shuffle(asList)
,你只是在洗牌房屋的顺序,但它们的居民仍然是一样的。
所以回答你的问题:
至少对于第一部分,是否可以对collections.shuffle进行简单的调整,以适应3D数组?
否,因为集合接口仅适用于列表、队列 deque 等对象。不是数组!因此,Collections.shuffle不会按照您想要的方式在数组上工作。但不要害怕!有一个函数可以使数组的行为像列表,Arrays.asLists。您可以对其进行一些研究,看看它是否可以解决您的问题,但我强烈建议您使用类,它会非常干净,更简单!(即使您是初学者)。
为答案做一个类,为问题做一个类,为问题库做一个类。
您的程序将有一个问题库列表,其中将有一个问题列表,问题将有一个答案列表。
如果你使用Collections.shuffle QuestionBank,你将随机化问题的顺序,如果你随机化这个问题,你将随机化他们答案的顺序。