我如何根据您所在的级别从列表中挑选几乎随机的问题?
How can I pick almost random questions from a list depending on which level you are on?
我正在做一个项目,我想根据你所在的级别选择不同的问题。
例如,我希望我的系统在前 25 个级别中以 80% 的几率选择简单的问题,以 20% 的几率选择中等问题。最后80级我希望难度慢慢增加,系统会100%只挑难的题。我怎样才能以数学方式编写一个工作缓慢增加的图形来实现我的数组选择器?
我曾尝试用以下方式随机播放 ArrayList
个对象:
Collections.shuffle(random);
例如为了获得百分比,但我应该有一个更简单的解决方法。
难以解释,但希望您能理解,如果您需要更多信息,请询问。
我正在 Android studio
上进行 libgdx 项目
您有几个问题包含在一个问题中,这使得您的问题对于这个站点来说有点宽泛,但让我们分解一下您的问题:
- 创建一个具有不同难度级别的问题 class。我们称之为 class
Question
和难度级别 Difficulty
- 创建一个 class 将这些问题保存在一个或多个集合中,并允许用户从这个 class 中请求一个随机问题。我们称此为 class
QuestionCollection
以及用于请求随机问题的方法 public Question getRandomQuestion(...)
。
- 允许用户有自己的进步水平。这可以是
User
class
- 可能从请求中收到的问题的分布
getRandomQuestion(...)
将取决于用户的进步水平
首先封装难度级别,让我们创建一个枚举,它有 3 个(或更多)级别:
public enum Difficulty {
EASY, MEDIUM, HARD
}
然后问题 class 可以有一个 private Difficulty difficulty;
字段,在其构造函数中设置一个,并使用 public getter 方法 public Difficulty getDifficulty()
。一个简化的问题 class 可能看起来像这样:
public class Question {
private String question;
private String answer;
private Difficulty difficulty;
public Question(String question, String answer, Difficulty difficulty) {
this.question = question;
this.answer = answer;
this.difficulty = difficulty;
}
public String getQuestion() {
return question;
}
public String getAnswer() {
return answer;
}
public Difficulty getDifficulty() {
return difficulty;
}
}
同样,这一切都过于简单化了,但它可以用来帮助说明问题和可能的解决方案。如果需要,您可以让 class 实现 Comparable<Question>
,并使用难度来帮助进行比较,并允许您按难度对 List<Question>
进行排序。
那么所有这一切的关键将是 QuestionCollection
class,它包含问题集合并具有 getRandomQuestion(...)
方法——如何实现这个。
一种方法是不要担心此时用户的进步水平,而是给 getRandomQuestion(...)
方法一些参数,让 QuestionCollection
知道要使用什么分布。在我看来最简单的方法是给它一个相对的难度频率,Difficulty.EASY
、Difficulty.MEDIUM
和 Difficulty.HARD
的百分比,例如:
public Question getRandomQuestion(int percentEasy, int percentMedium, int percentHard) {
// ... code here to get the random question
}
好的,现在我们要了解如何构建 QuestionCollection
class 的内部工作原理,然后使用它根据参数百分比正确分配随机问题。可能最简单的是将问题放入其自己的列表中,例如基于其难度级别的 ArrayList——所以这里有 3 个列表,一个用于简单问题,一个用于中等问题,一个用于困难问题。
所以:
private List<Question> easyQuestions = new ArrayList<>();
private List<Question> mediumQuestions = new ArrayList<>();
private List<Question> hardQuestions = new ArrayList<>();
或者另一个可能 cleaner 解决方案是使用 Map<Difficulty, List<Question>>
而不是单独的列表,但我现在会保持简单,并将其保留在 3 个列表中。
然后 class 将有一个 public void addQuestion(Question q)
方法,可以根据难度级别将问题添加到正确的列表中:
public void addQuestion(Question q) {
switch (q.getDifficulty()) {
case EASY:
easyQuestions.add(q);
break;
case MEDIUM:
mediumQuestions.add(q);
break;
case HARD:
hardQuestions.add(q);
}
}
好的,所以我们的列表中充满了问题,我们现在的核心问题是如何获得正确的随机分布?我会推荐一个两步过程——首先使用 Math.random()
或随机 class 的实例来选择 从哪个列表 中获取问题,然后使用使用随机化 select 所选列表中的随机问题。
所以第一步,获取随机列表可能如下所示:
// declare variable before the if blocks
List<Question> randomList = null;
// get a random int from 0 to 99
int rand = (int) (100 * Math.random());
// get the random list using basic math and if blocks
if (rand < percentEasy) {
randomList = easyQuestions;
} else if (rand < percentEasy + percentMedium) {
randomList = mediumQuestions;
} else {
randomList = hardQuestions;
}
OK,一旦获得了randomList,就从中得到一个随机问题:
// first get a random index to the list from 0 to < size
int size = randomList.size();
int listIndex = (int)(size * Math.random());
Question randomQuestion = randomList.get(listIndex);
return randomQuestion;
整个QuestionCollection
class(简化版)可能是这样的:
// imports here
public class QuestionCollection {
private List<Question> easyQuestions = new ArrayList<>();
private List<Question> mediumQuestions = new ArrayList<>();
private List<Question> hardQuestions = new ArrayList<>();
public void addQuestion(Question q) {
switch (q.getDifficulty()) {
case EASY:
easyQuestions.add(q);
break;
case MEDIUM:
mediumQuestions.add(q);
break;
case HARD:
hardQuestions.add(q);
}
}
public Question getRandomQuestion(int percentEasy, int percentMedium, int percentHard) {
// if the numbers don't add up to 100, the distribution is broken -- throw an exception
if (percentEasy + percentMedium + percentHard != 100) {
String format = "For percentEasy: %d, percentMedium: %d, percentHard: %d";
String text = String.format(format, percentEasy, percentMedium, percentHard);
throw new IllegalArgumentException(text);
}
List<Question> randomList = null;
int rand = (int) (100 * Math.random());
if (rand < percentEasy) {
randomList = easyQuestions;
} else if (rand < percentEasy + percentMedium) {
randomList = mediumQuestions;
} else {
randomList = hardQuestions;
}
// we've now selected the correct List
// now get a random question from the list:
// first get a random index to the list from 0 to < size
int size = randomList.size();
int listIndex = (int)(size * Math.random());
Question randomQuestion = randomList.get(listIndex);
return randomQuestion;
}
}
为了测试概念证明,测试程序显示分发有效:
// imports
public class QuestionFun {
public static void main(String[] args) {
// create QuestionCollection object
QuestionCollection questionCollection = new QuestionCollection();
// fill it with questions with random difficulty
for (int i = 0; i < 1000; i++) {
String question = "Question #" + i;
String answer = "Answer #" + i;
int randomIndex = (int) (Difficulty.values().length * Math.random());
Difficulty difficulty = Difficulty.values()[randomIndex];
Question q = new Question(question, answer, difficulty);
questionCollection.addQuestion(q);
}
Map<Difficulty, Integer> frequencyDistMap = new EnumMap<>(Difficulty.class);
for (Difficulty diff : Difficulty.values()) {
frequencyDistMap.put(diff, 0);
}
int easyPercent = 20;
int mediumPercent = 70;
int hardPercent = 10;
int questionCount = 10000;
for (int i = 0; i < questionCount; i++) {
Question q = questionCollection.getRandomQuestion(easyPercent, mediumPercent, hardPercent);
Difficulty difficulty = q.getDifficulty();
int currentCount = frequencyDistMap.get(difficulty);
currentCount++;
frequencyDistMap.put(difficulty, currentCount);
}
System.out.println("Difficulty: Count (Percent)");
String format = "%-12s %4d (%02d)%n";
for (Difficulty difficulty : Difficulty.values()) {
int number = frequencyDistMap.get(difficulty);
int percent = (int) Math.round((100.0 * number) / questionCount);
System.out.printf(format, difficulty + ":", number, percent);
}
}
}
其中returns原分配百分比:
Difficulty: Count (Percent)
EASY: 200325 (20)
MEDIUM: 699341 (70)
HARD: 100334 (10)
我正在做一个项目,我想根据你所在的级别选择不同的问题。
例如,我希望我的系统在前 25 个级别中以 80% 的几率选择简单的问题,以 20% 的几率选择中等问题。最后80级我希望难度慢慢增加,系统会100%只挑难的题。我怎样才能以数学方式编写一个工作缓慢增加的图形来实现我的数组选择器?
我曾尝试用以下方式随机播放 ArrayList
个对象:
Collections.shuffle(random);
例如为了获得百分比,但我应该有一个更简单的解决方法。
难以解释,但希望您能理解,如果您需要更多信息,请询问。 我正在 Android studio
上进行 libgdx 项目您有几个问题包含在一个问题中,这使得您的问题对于这个站点来说有点宽泛,但让我们分解一下您的问题:
- 创建一个具有不同难度级别的问题 class。我们称之为 class
Question
和难度级别Difficulty
- 创建一个 class 将这些问题保存在一个或多个集合中,并允许用户从这个 class 中请求一个随机问题。我们称此为 class
QuestionCollection
以及用于请求随机问题的方法public Question getRandomQuestion(...)
。 - 允许用户有自己的进步水平。这可以是
User
class - 可能从请求中收到的问题的分布
getRandomQuestion(...)
将取决于用户的进步水平
首先封装难度级别,让我们创建一个枚举,它有 3 个(或更多)级别:
public enum Difficulty {
EASY, MEDIUM, HARD
}
然后问题 class 可以有一个 private Difficulty difficulty;
字段,在其构造函数中设置一个,并使用 public getter 方法 public Difficulty getDifficulty()
。一个简化的问题 class 可能看起来像这样:
public class Question {
private String question;
private String answer;
private Difficulty difficulty;
public Question(String question, String answer, Difficulty difficulty) {
this.question = question;
this.answer = answer;
this.difficulty = difficulty;
}
public String getQuestion() {
return question;
}
public String getAnswer() {
return answer;
}
public Difficulty getDifficulty() {
return difficulty;
}
}
同样,这一切都过于简单化了,但它可以用来帮助说明问题和可能的解决方案。如果需要,您可以让 class 实现 Comparable<Question>
,并使用难度来帮助进行比较,并允许您按难度对 List<Question>
进行排序。
那么所有这一切的关键将是 QuestionCollection
class,它包含问题集合并具有 getRandomQuestion(...)
方法——如何实现这个。
一种方法是不要担心此时用户的进步水平,而是给 getRandomQuestion(...)
方法一些参数,让 QuestionCollection
知道要使用什么分布。在我看来最简单的方法是给它一个相对的难度频率,Difficulty.EASY
、Difficulty.MEDIUM
和 Difficulty.HARD
的百分比,例如:
public Question getRandomQuestion(int percentEasy, int percentMedium, int percentHard) {
// ... code here to get the random question
}
好的,现在我们要了解如何构建 QuestionCollection
class 的内部工作原理,然后使用它根据参数百分比正确分配随机问题。可能最简单的是将问题放入其自己的列表中,例如基于其难度级别的 ArrayList——所以这里有 3 个列表,一个用于简单问题,一个用于中等问题,一个用于困难问题。
所以:
private List<Question> easyQuestions = new ArrayList<>();
private List<Question> mediumQuestions = new ArrayList<>();
private List<Question> hardQuestions = new ArrayList<>();
或者另一个可能 cleaner 解决方案是使用 Map<Difficulty, List<Question>>
而不是单独的列表,但我现在会保持简单,并将其保留在 3 个列表中。
然后 class 将有一个 public void addQuestion(Question q)
方法,可以根据难度级别将问题添加到正确的列表中:
public void addQuestion(Question q) {
switch (q.getDifficulty()) {
case EASY:
easyQuestions.add(q);
break;
case MEDIUM:
mediumQuestions.add(q);
break;
case HARD:
hardQuestions.add(q);
}
}
好的,所以我们的列表中充满了问题,我们现在的核心问题是如何获得正确的随机分布?我会推荐一个两步过程——首先使用 Math.random()
或随机 class 的实例来选择 从哪个列表 中获取问题,然后使用使用随机化 select 所选列表中的随机问题。
所以第一步,获取随机列表可能如下所示:
// declare variable before the if blocks
List<Question> randomList = null;
// get a random int from 0 to 99
int rand = (int) (100 * Math.random());
// get the random list using basic math and if blocks
if (rand < percentEasy) {
randomList = easyQuestions;
} else if (rand < percentEasy + percentMedium) {
randomList = mediumQuestions;
} else {
randomList = hardQuestions;
}
OK,一旦获得了randomList,就从中得到一个随机问题:
// first get a random index to the list from 0 to < size
int size = randomList.size();
int listIndex = (int)(size * Math.random());
Question randomQuestion = randomList.get(listIndex);
return randomQuestion;
整个QuestionCollection
class(简化版)可能是这样的:
// imports here
public class QuestionCollection {
private List<Question> easyQuestions = new ArrayList<>();
private List<Question> mediumQuestions = new ArrayList<>();
private List<Question> hardQuestions = new ArrayList<>();
public void addQuestion(Question q) {
switch (q.getDifficulty()) {
case EASY:
easyQuestions.add(q);
break;
case MEDIUM:
mediumQuestions.add(q);
break;
case HARD:
hardQuestions.add(q);
}
}
public Question getRandomQuestion(int percentEasy, int percentMedium, int percentHard) {
// if the numbers don't add up to 100, the distribution is broken -- throw an exception
if (percentEasy + percentMedium + percentHard != 100) {
String format = "For percentEasy: %d, percentMedium: %d, percentHard: %d";
String text = String.format(format, percentEasy, percentMedium, percentHard);
throw new IllegalArgumentException(text);
}
List<Question> randomList = null;
int rand = (int) (100 * Math.random());
if (rand < percentEasy) {
randomList = easyQuestions;
} else if (rand < percentEasy + percentMedium) {
randomList = mediumQuestions;
} else {
randomList = hardQuestions;
}
// we've now selected the correct List
// now get a random question from the list:
// first get a random index to the list from 0 to < size
int size = randomList.size();
int listIndex = (int)(size * Math.random());
Question randomQuestion = randomList.get(listIndex);
return randomQuestion;
}
}
为了测试概念证明,测试程序显示分发有效:
// imports
public class QuestionFun {
public static void main(String[] args) {
// create QuestionCollection object
QuestionCollection questionCollection = new QuestionCollection();
// fill it with questions with random difficulty
for (int i = 0; i < 1000; i++) {
String question = "Question #" + i;
String answer = "Answer #" + i;
int randomIndex = (int) (Difficulty.values().length * Math.random());
Difficulty difficulty = Difficulty.values()[randomIndex];
Question q = new Question(question, answer, difficulty);
questionCollection.addQuestion(q);
}
Map<Difficulty, Integer> frequencyDistMap = new EnumMap<>(Difficulty.class);
for (Difficulty diff : Difficulty.values()) {
frequencyDistMap.put(diff, 0);
}
int easyPercent = 20;
int mediumPercent = 70;
int hardPercent = 10;
int questionCount = 10000;
for (int i = 0; i < questionCount; i++) {
Question q = questionCollection.getRandomQuestion(easyPercent, mediumPercent, hardPercent);
Difficulty difficulty = q.getDifficulty();
int currentCount = frequencyDistMap.get(difficulty);
currentCount++;
frequencyDistMap.put(difficulty, currentCount);
}
System.out.println("Difficulty: Count (Percent)");
String format = "%-12s %4d (%02d)%n";
for (Difficulty difficulty : Difficulty.values()) {
int number = frequencyDistMap.get(difficulty);
int percent = (int) Math.round((100.0 * number) / questionCount);
System.out.printf(format, difficulty + ":", number, percent);
}
}
}
其中returns原分配百分比:
Difficulty: Count (Percent)
EASY: 200325 (20)
MEDIUM: 699341 (70)
HARD: 100334 (10)