我有两个学生对象。
class Student{
int physics;
int english;
int chemistry;
}
我需要将每个科目的学生A分数与所有科目的学生B分数进行比较。
物理学中的标记需要与物理,英语,化学中的B标记进行比较。 同样A的英语与B的所有三个。
如果至少有一个比赛说A的化学标记等于B的英文标记, 然后停止执行并返回false。
我的逻辑是
if(a.getPhysics==b.getPhysics || a.getPhysics==b.getEnglish || a.phy==b.chem || ...){
return false;
}
这是更好还是其他任何好的逻辑??????
答案 0 :(得分:1)
稍微改进就是在Student类中创建一个方法来实现它。
答案 1 :(得分:1)
嗯,在任何情况下你都必须进行O(n^2)
比较,问题是代码的清洁程度。
你现在建议的6个布尔比较是好的,如果你有30个科目怎么办?你会保持你需要进行的数百次比较吗?
保持简单,我希望将成绩保持在List
或Map
,然后进行嵌套迭代:
for (int gradeA : thisStudent.getGrades()) {
for (int gradeB : otherStudent.getGrades()) {
if (gradeA == gradeB) return false;
}
}
return true;
当然这个代码需要适应你的场景(List vs. Map上的不同迭代,每次不检查每个等级的优化,从中提取方法等等)
答案 2 :(得分:1)
这些属性(课程物理,英语,......)不应该在Student
课程中。一个更好的选择是创建一个CourseModel
,您可以在其中存储所有课程,并跟踪所有注册课程的Student
。从您的CourseModel
,您可以查询特定的Student
并获取所有课程(作为数组/集合)。当你有两个集合/数组时,只需创建一个嵌套的for语句来比较所有这些。
答案 3 :(得分:1)
使用HashSet:
Set<Integer> aMarks = new HashSet<Integer>();
Set<Integer> bMarks = new HashSet<Integer>();
Collections.addAll(aMarks, 2, 3, 9);
Collections.addAll(bMarks, 4, 2, 2);
boolean check = Collections.disjoint(aMarks, bMarks);
return check;
这些值仅供测试。您可以使用新方法Student.getMarksAsSet()
答案 4 :(得分:1)
您可以为Student
添加将其标记作为集合返回的功能:
public class Student {
private int physics;
private int english;
private int chemistry;
public Student(int physics, int english, int chemistry) {
this.physics = physics;
this.english = english;
this.chemistry = chemistry;
}
public Set<Integer> marks() {
return new HashSet<Integer>(Arrays.asList(physics, english, chemistry));
}
}
然后,当试图确定两个学生是否匹配时,你需要看到的是他们的两组标记是否是不相交的,如StudentMatcher
所做的那样:
public class StudentMatcher {
public boolean matches(Student student1, Student student2) {
Set<Integer> studentMarks1 = student1.marks();
Set<Integer> studentMarks2 = student2.marks();
return haveIntersection(studentMarks1, studentMarks2);
}
private boolean haveIntersection(Set<Integer> studentMarks1, Set<Integer> studentMarks2) {
return studentMarks1.removeAll(studentMarks2);
}
}
以下是验证其有效的单元测试:
public class StudentMatcherTest {
@Test
public void matches() {
StudentMatcher matcher = new StudentMatcher();
Student student1 = new Student(34, 45, 66);
Student student2 = new Student(99, 55, 34);
Student student3 = new Student(11, 22, 33);
assertTrue("Should match", matcher.matches(student1, student2));
assertFalse("Should not match", matcher.matches(student1, student3));
}
}
可以做的更多,以使这更好,但我认为你的代码比你发布的更复杂,所以希望这足以让你走上更好的道路。
答案 5 :(得分:0)
如果标记在一个小范围内(AF而不是百分比),并且您需要比较许多主题中的标记而不是您给出的三个标记,请填充一组布尔值以保存第一个学生是否具有给定标记,然后第二次检查数组是否有值集。那将是O(N + M),其中N是受试者的数量,M是可能等级的数量。
如果你只有三个科目,那么硬编码的测试并不是那么糟糕 - 你需要六行才能从中获得标记。