If I were wrong, then one would have been enough

"만약 내가 정말로 틀렸다면 단 한 사람의 반대로도 충분 했을거야."

알고리즘/Problem solving

[프로그래머스] [Python] H-Index 풀이방법 + Test case

sumi_ni 2021. 1. 14. 14:46

 

목차

 

1. 문제 내용

 

2. 문제 해석

 

3. 코드 작성

 

4. 최종 코드

 

5. 테스트 케이스 부록

 


1. 문제 내용

  어떤 과학자가 발표한 논문 n 중, h번 이상 인용된 논문이 h 이상이고 나머지 논문이 h번 이하 인용되었다면 h의 최댓값이 이 과학자의 H-Index입니다.

  어떤 과학자가 발표한 논문의 인용 횟수를 담은 배열 citations가 매개변수로 주어질 때, 이 과학자의 H-Index를 return 하도록 solution 함수를 작성해주세요.

# 제한상황

  • 과학자가 발표한 논문의 수는 1편 이상 1,000편 이하입니다.

  • 논문별 인용 횟수는 0회 이상 10,000회 이하입니다.

2. 문제 해석

 이 문제는 문제를 푸는 과정은 별로 어렵지 않으나 문제를 이해하는 과정이 난이도가 있다고 생각한다.

우선 문제의 설명과 아래에 있는 링크의 H-Index의 개념을 어느 정도 읽고 이해를 한 후 진행을 하면 좋을 것 같다.

www.ibric.org/myboard/read.php?Board=news&id=270333

 

[연구논문을 위한 핵심 10단계] H-지수(H-Index) 란 무엇인가?

일반적으로 특정 연구원의 연구성과를 평가하기 위해 얼마나 많은 논문을 발표 하였는지를 보게됩니다. 그러나 단순히 발표한 논문 수로만 그 연구원의 연구 업적을 평가 하기에는 발표한 논문

www.ibric.org

citations = [10,8,5,4,3] -> H-Index = 4

인용수가 4이상인 논문의 개수가 4개 이상이라는 것이다.

위 개념을 통해 대략 H 값의 범위를 줄여보자면 H의 최댓값은 리스트의 개수인 것을 알 수 있다. 왜냐하면 인용수가 100 이상인 논문 1개가 있더라도 학자가 논문을 100편 이상 쓰지 않았으면 H-Index 값은 100이 될 수 없기 때문이다.

 

추가적인 예시로 개념을 좀 더 구체화시켜보자

  앞선 문제 설명은 이러했다.

  어떤 과학자가 발표한 논문 n편 중, h번 이상 인용된 논문이 h편 이상이고 나머지 논문이 h번 이하 인용되었다면 h의 최댓값이 이 과학자의 H-Index입니다.

  어떤 과학자가 발표한 논문의 인용 횟수를 담은 배열 citations가 매개변수로 주어질 때, 이 과학자의 H-Index를 return 하도록 solution 함수를 작성해주세요.

  이를 바탕으로 아래의 테스트 케이스를 생각해보자

 

citations = [6,6,6,6,6,1] 일 때  이 과학자의 H-Index는?

 

이 상황에서 답은 5이다.

 

  위 예시를 든 이유는 일부 사람들이 h값을 citations 리스트 안에 있는 값 중에서 고르려고 하기 때문이다.

  이런 케이스까지 성공적으로 해결하는 코드를 작성하기 위해서 우리는 H-index의 최댓값과 citations 리스트의 길이의 관계를 고려하면서 문제를 풀어나가야 한다.

 


3. 코드 작성

  시간 복잡도(Big-O)까지 고려하려면 H-index의 최댓값(리스트의 길이)부터 검사하며 조건에 맞을 시 이후 계산은 생략하는 식으로 연산을 최소화하도록 코드를 작성하는 게 좋을 듯하다. 하지만 처음부터 너무 많은걸 고려하려고 하는 것은 여간 쉬운 일이 아니기에 여기서는 문제의 이해를 도와주는 코드를 작성할 것이다.

(* 추가적으로 코드의 길이를 더욱 줄이고 싶으면 citations 리스트를 내림차순으로 정렬한 후, 정렬의 특징을 이용해 h번 이상 인용된 값들을 간단하게 생각하는 방법도 있다. ex) list [3]의 값이 6일경우 list[3] 다음 값들은 항상 6 이상인 특징 물론 올림 차순으로 정리하는 것도 가능하다.)

 

 지금부터 작성하는 코드는 H-Index의 최솟값(0)부터 1씩 증가하며 조건을 확인하는 코드다.


h_index == 최대 H-Index값을 저장, tmp_h == 임시적으로 현재 검토 중인 H-Index값을 저장

def solution(citations):
    h_index = 0
    for tmp_h in range(len(citations)+1):
    
    return h_index

check_num == h번 인용된 논문이 몇 개인지 저장, citation == citations list에서 선택한 값

h값을 0부터 검사함 -> h값 이상 인용된 논문의 수의 개수를 구함

def solution(citations):
    h_index = 0
    for tmp_h in range(len(citations)+1):
        check_num = 0
        for citation in citations:
            if (tmp_h <= citation):
                check_num += 1
     
    return h_index

마지막으로 조건문을 이용하여 h 값을 결정한다.

만약 h번 이상 인용된 논문이 h개 이상이면 h_index 값은 tmp_h값으로 정해지고 아니면 h_index 값은 지금 검사 중인 tmp_h값보다 1 작은 수라는 것을 추가하였다.

def solution(citations):
    h_index = 0
    for tmp_h in range(len(citations)+1):
        check_num = 0
        for citation in citations:
            if (tmp_h <= citation):
                check_num += 1
        if (tmp_h > check_num):
            h_index = tmp_h - 1
            break
        else :
            h_index = tmp_h
    return h_index

4. 최종 풀이 코드

def solution(citations):
    h_index = 0
    for tmp_h in range(len(citations)+1):
        check_num = 0
        for citation in citations:
            if (tmp_h <= citation):
                check_num += 1
        if (tmp_h > check_num):
            h_index = tmp_h - 1
            break
        else :
            h_index = tmp_h
    return h_index

위 코드 테스트 결과

 


5. 테스트 케이스 부록

solution([3, 0, 6, 1, 5]) # 3
solution([10,8,5,4,3]) # 4
solution([25,8,5,3,3]) # 3
solution([8,7,7,6,5,5,3]) # 5
solution([47,42,32,28,24,22,17,15,10,10,8]) # 10
solution([12,11,10,9,8,1]) # 5
solution([6,6,6,6,6,1]) # 5
solution([20,21,22,23]) # 4
solution([4,4,4]) # 3

# 번호 => H-Index 값이다

테스트를 좀 더 꼼꼼히 하고 싶으면 정렬되어 있는 리스트 값들의 순서를 바꿔보는 것 또한 좋다.