2009-11-07 9 views
0

두 학생 개체가 있습니다.개체 비교

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

이 더 나은 또는 다른 좋은 논리입니다 ??????

답변

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; 

대지도, 매번 각 등급을 확인하지 않음으로써 최적화,이 중에서 방법 추출하기 ...)

1

약간의 improvment는 그것을 할 학생 클래스에있는 방법을 만드는 것입니다.

1

이러한 속성 (물리, 영어 등)은 Student 클래스에 있어서는 안됩니다. . 더 나은 옵션은 CourseModel을 작성하여 코스를 모두 저장하고 코스에 등록한 모든 Student을 추적하는 것입니다. CourseModel에서 특정 Student을 쿼리하고 모든 과정을 다시 가져올 수 있습니다 (배열/컬렉션). 콜렉션/배열이 두 개일 경우 중첩 된 for 문을 작성하여 모두 비교하십시오.

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 수있는 기능을 추가 할 수 Student.getMarksAsSet()

+0

어떤 과목이 어떤 과목보다 세분성이 떨어지기 때문에 다른 데이터 구조와 함께 세트의 성적을 저장해야합니다. –

+0

하지만 불행히도 나는 학생 대상을 변경할 수 없습니다. 병 안에 있어요. – crazyTechie

+0

학생 클래스를 변경할 수 없다면, 하나씩 차례로 마크를 추가하십시오 :'aMarks.add (a.getPhysics)','aMarks.add (a.getEnglish) '... –

1

새로운 방법 : 두 학생이 일치하는지 확인하려고 할 때, 그리고

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은 가능한 성적의 수입니다.

과목이 3 개 밖에없는 경우 테스트를 하드 코드화하는 것이 그리 나쁘지 않습니다. 어쨌든 각각에서 마크를 얻으려면 6 개의 줄이 필요합니다.