[РЕШЕНО] См. решение выше.
Я работаю над программой Java, в которой у меня есть класс ClassGenerator, который управляет оценками учащихся с течением времени и должен разделить их на группы на основе на равных медианах. Вот упрощенная версия того, чего я пытаюсь достичь:
У меня есть ученики с оценками за три года, хранящиеся в таких массивах:
Мне нужно реализовать метод равныхMediansGroups() в ClassGenerator, который делит учащихся на группы numGroups на основе их прошлогодних оценок, гарантируя, что каждая группа имеет примерно равные медианы.
Вот что у меня есть, но это не дает правильных результатов:
Group median: 20.0
Group students: [9.0, 8.0, 7.0]
Group median: 50.0
Group students: [6.0, 5.0, 4.0]
Group median: 80.0
Group students: [3.0, 2.0, 1.0]
Может ли кто-нибудь помочь мне понять, какие корректировки необходимы в моем методеqualMediansGroups() для достижения правильной группировки на основе равных медиан последних оценок учащихся? Если есть новые ученики без оценок, их следует распределить равномерно по группам, поскольку они не влияют на медиану какой-либо группы.
Спасибо!
[РЕШЕНО]
Я нашел следующее решение:
class ClassGenerator {
private ClassGenerator() {}
public static List partitionsEqually(int[] students, double[][] marksOverTime, int numGroups) {
if (students.length != marksOverTime.length)
throw new IllegalArgumentException("The number of students and marks must be equal.");
else if (Arrays.stream(marksOverTime).anyMatch(m -> Arrays.stream(m).anyMatch(mark -> mark < 0 || mark > 100)))
throw new IllegalArgumentException("Marks must be between 0 and 100.");
// Create a list of students with their marks
List studentMarksList = new ArrayList();
for (int i = 0; i < students.length; i++) {
studentMarksList.add(new StudentMarks(students[i], marksOverTime[i]));
}
// Sort students based on their last marks
studentMarksList.sort(Comparator.comparingDouble(StudentMarks::getLastMark));
// Initialize partitions
List partitions = new ArrayList();
for (int i = 0; i < numGroups; i++) partitions.add(new ArrayList());
// Distribute students into partitions
for (int i = 0; i < studentMarksList.size(); i++)
partitions.get(i % numGroups).add(studentMarksList.get(i).studentId());
return partitions;
}
private record StudentMarks(int studentId, double[] marks) {
private StudentMarks(int studentId, double[] marks) {
this.studentId = studentId;
this.marks = Arrays.copyOf(marks, marks.length);
}
private double getLastMark() {
return marks.length > 0 ? marks[marks.length - 1] : -1;
}
}
[РЕШЕНО] См. решение выше. Я работаю над программой Java, в которой у меня есть класс ClassGenerator, который управляет оценками учащихся с течением времени и должен разделить их на группы на основе на равных медианах. Вот упрощенная версия того, чего я пытаюсь достичь: У меня есть ученики с оценками за три года, хранящиеся в таких массивах: [code]int[] students = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; double[][] marksOverTime = { {80, 85, 90}, {70, 75, 80}, {60, 65, 70}, {50, 55, 60}, {40, 45, 50}, {30, 35, 40}, {20, 25, 30}, {10, 15, 20}, {0, 5, 10}, {} }; [/code] Мне нужно реализовать метод равныхMediansGroups() в ClassGenerator, который делит учащихся на группы numGroups на основе их прошлогодних оценок, гарантируя, что каждая группа имеет примерно равные медианы. Вот что у меня есть, но это не дает правильных результатов: [code]public List equalMediansGroups() { int[] studentsWithMarks = getStudentsWithMarks(); Arrays.sort(studentsWithMarks, Comparator.comparingDouble(this::getLastMark).reversed());
int groupSize = studentsWithMarks.length / numGroups; int remainder = studentsWithMarks.length % numGroups;
List groups = new ArrayList();
int index = 0; for (int i = 0; i < numGroups; i++) { int start = index; int end = start + groupSize + (i < remainder ? 1 : 0);
ClassGenerator classGenerator = new ClassGenerator(students, marksOverTime, 3); List groups = classGenerator.equalMediansGroups();
// Print groups for (double[] group : groups) { System.out.println("Group median: " + group[0]); System.out.println("Group students: " + Arrays.toString(Arrays.copyOfRange(group, 1, group.length))); System.out.println(); } } [/code] Результат, который я сейчас получаю, неудовлетворительный: [code]Group median: 20.0 Group students: [9.0, 8.0, 7.0]
Group median: 50.0 Group students: [6.0, 5.0, 4.0]
Group median: 80.0 Group students: [3.0, 2.0, 1.0] [/code] Может ли кто-нибудь помочь мне понять, какие корректировки необходимы в моем методеqualMediansGroups() для достижения правильной группировки на основе равных медиан последних оценок учащихся? Если есть новые ученики без оценок, их следует распределить равномерно по группам, поскольку они не влияют на медиану какой-либо группы. Спасибо! [РЕШЕНО] Я нашел следующее решение: [code]class ClassGenerator { private ClassGenerator() {}
public static List partitionsEqually(int[] students, double[][] marksOverTime, int numGroups) { if (students.length != marksOverTime.length) throw new IllegalArgumentException("The number of students and marks must be equal."); else if (Arrays.stream(marksOverTime).anyMatch(m -> Arrays.stream(m).anyMatch(mark -> mark < 0 || mark > 100))) throw new IllegalArgumentException("Marks must be between 0 and 100.");
// Create a list of students with their marks List studentMarksList = new ArrayList(); for (int i = 0; i < students.length; i++) { studentMarksList.add(new StudentMarks(students[i], marksOverTime[i])); }
// Sort students based on their last marks studentMarksList.sort(Comparator.comparingDouble(StudentMarks::getLastMark));
// Initialize partitions List partitions = new ArrayList(); for (int i = 0; i < numGroups; i++) partitions.add(new ArrayList());
// Distribute students into partitions for (int i = 0; i < studentMarksList.size(); i++) partitions.get(i % numGroups).add(studentMarksList.get(i).studentId());