У вас есть несколько проблем, заключенных в один вопрос, что делает ваш вопрос немного более широким для этого сайта, но давайте разберем ваши проблемы:
- Создайте класс вопросов с различными уровнями сложности.Давайте назовем этот класс
Question
и уровень сложности Difficulty
- Создайте класс, который содержит эти вопросы в коллекции или в коллекциях какого-либо рода, и разрешите пользователю запрашивать случайный вопрос из этого класса.Давайте назовем этот класс
QuestionCollection
и метод, используемый для запроса случайного вопроса, public Question getRandomQuestion(...)
. - Разрешить пользователю иметь свой собственный уровень продвижения.Это может быть
User
класс - Распределение вопросов, возможно, полученных из запроса
getRandomQuestion(...)
, будет зависеть от уровня продвижения пользователя
Итак, сначала инкапсулируем уровеньсложности, давайте создадим перечисление, которое имеет 3 (или более) уровня:
public enum Difficulty {
EASY, MEDIUM, HARD
}
Тогда класс Question может иметь поле private Difficulty difficulty;
, одно в своем конструкторе и с открытым методом getter.public Difficulty getDifficulty()
.Упрощенный класс Question может выглядеть примерно так:
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;
}
}
Опять же, это слишком упрощенное решение, но его можно использовать для иллюстрации проблемы и возможного решения.При желании вы могли бы реализовать в этом классе Comparable<Question>
и использовать Трудность, чтобы помочь выполнить сравнение, и позволить вам сортировать List<Question>
по сложности.
Тогда ключом ко всему этому будетQuestionCollection
класс, который содержал набор (ы) вопросов и в котором был метод 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
, а затем использовать это, чтобы получить правильное распределение случайных вопросов, основанных на процентах параметров.Вероятно, самый простой - это поместить вопрос в свой собственный список, такой как ArrayList, основываясь на его уровне сложности - так что здесь 3 списка, один для EASY, один для MEDIUM и один для HARD вопросов.
Итак:
private List<Question> easyQuestions = new ArrayList<>();
private List<Question> mediumQuestions = new ArrayList<>();
private List<Question> hardQuestions = new ArrayList<>();
Или другое, возможно, чистое решение состоит в том, чтобы использовать Map<Difficulty, List<Question>>
вместо отдельных списков, но сейчас я сделаю все просто иоставьте это в 3 Списках.
Тогда у класса будет метод 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()
или экземпляр класса Random, чтобы выбрать из какого списка , чтобы получить вопрос, а затем используйте команду randomization, чтобы выбрать случайный вопрос извыбранный список.
Итак, первый шаг для получения случайного списка может выглядеть так:
// 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;
}
ОК, как только будет получен 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
(упрощенная версия) может выглядеть так:
// 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);
}
}
}
Возвращает исходный процент распределения:
Difficulty: Count (Percent)
EASY: 200325 (20)
MEDIUM: 699341 (70)
HARD: 100334 (10)