2009-11-07 241 views
0

我有兩個學生對象。比較對象

class Student{ 
int physics; 
int english; 
int chemistry; 
} 

我需要比較每個科目的學生A分數和所有科目的學生B分數。

物理學中的標記需要與物理學,英語,化學中的B標記進行比較。 同樣,一個英語與所有三個B.

如果有ATLEAST一個比賽說A的化學標記等於B的英文標記,然後 停止執行,並返回假的。

我的邏輯是

if(a.getPhysics==b.getPhysics || a.getPhysics==b.getEnglish || a.phy==b.chem || ...){ 
    return false; 
} 

這是好還是什麼其他好的邏輯??????

回答

1

那麼,在任何情況下你都必須做出O(n^2)的比較,問題是代碼是多麼乾淨。

你現在建議的是6個布爾比較好,如果你有30個主題?你會保持你需要做的比較嗎?

保持簡單,我寧願保持成績的ListMap,然後做一個嵌套的迭代:

for (int gradeA : thisStudent.getGrades()) { 
    for (int gradeB : otherStudent.getGrades()) { 
     if (gradeA == gradeB) return false; 
    } 
} 
return true; 

當然需要這個代碼能夠適應您的情況(首不同的迭代對比地圖,通過每次不檢查每個等級進行優化,從中提取出一種方法等等)

1

稍微改進一下就是在Student類中創建一個方法來完成它。

1

這些屬性(課程物理,英語,...)不應該在Student類。一個更好的選擇是創建一個CourseModel,在那裏你存儲所有課程,並跟蹤所有參加課程的Student。從CourseModel開始,您可以查詢特定的Student並獲取所有課程(作爲數組/集合)。當你有兩個集合/數組時,只需創建一個嵌套的for-statement來比較它們。

1

使用HashSets:

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; 

爲不用測試。您可以更改Collections.addAll(...)用新的方法Student.getMarksAsSet()

+0

除了另一個數據結構之外,您還需要在集合中保存分數,因爲您會丟失哪個分數是哪個主題的粒度。 – 2009-11-07 11:10:09

+0

但不幸的是,我無法更改學生對象。它在一個罐子裏。 – crazyTechie 2009-11-07 11:17:14

+0

如果你不能更改Student類,請逐個添加你的標記:'aMarks.add(a.getPhysics)','aMarks.add(a.getEnglish)'...... – 2009-11-07 11:24:10

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)); 
    } 
} 

還有更多的事情可以做到這一點,但我假設你的代碼比你發佈的代碼更復雜,所以希望這足以讓你走上更好的道路。

0

如果標記的範圍很小(AF而非百分比),並且您需要比較多個主題中的標記而不是您給出的三個標記,則填充一組布爾值以確定第一個學生是否具有給定的標記,然後檢查數組是否有值。那將是O(N + M),其中N是主題的數量,M是可能的等級的數量。

如果你只有三個主題,硬編碼測試並沒有那麼糟糕 - 你需要六行來獲得每個標記。