Я работаю над программой Java, в которой у меня есть класс ClassGenerator, который управляет оценками учащихся с течением времени и должен разделить их на группы на основе на равных медианах. Вот упрощенная версия того, чего я пытаюсь достичь:
У меня есть ученики с оценками за три года, хранящиеся в таких массивах:
Код: Выделить всё
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},
{}
};
Вот что у меня есть, но это не дает правильных результатов:
Код: Выделить всё
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);
double median;
if ((end - start) % 2 == 0) {
median = (getLastMark(studentsWithMarks[end - 1]) + getLastMark(studentsWithMarks[start])) / 2.0;
} else {
median = getLastMark(studentsWithMarks[(start + end) / 2]);
}
double[] group = new double[end - start + 1];
group[0] = median;
for (int j = start; j < end; j++) {
group[j - start + 1] = studentsWithMarks[j];
}
groups.add(group);
index = end;
}
return groups;
}
public static void main(String[] args) {
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},
{}
};
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();
}
}
Код: Выделить всё
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]
Спасибо!
[РЕШЕНО]
Я нашел следующее решение:
Код: Выделить всё
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;
}
}
Подробнее здесь: https://stackoverflow.com/questions/786 ... ns-in-java