2015-01-27 6 views
0

텍스트의 문자 발생 수를 저장하는 해시 맵이 있습니다. 상위 3 번 항목을 인쇄하려고하는데 잘못 인쇄됩니다.해시 맵 상위 3 개 키 가져 오기

List<Entry<Character, Integer>> top3 = map.entrySet().stream() 
            .sorted(comparing(Entry::getValue, reverseOrder())) 
            .limit(3) 
            .collect(toList()); 

(*) 다음과 같은 수입과 :
import static java.util.Comparator.comparing;
import static java.util.Comparator.reverseOrder;
import static java.util.stream.Collectors.toList;

당신이 아래의 코드 (*)를 사용할 수있는 Java 8을

int max = 1000000000; 
for (int i = 1; i <= 3; i++) { 
    for (Character key : list.keySet()) { 
     if (list.get(key) < max) { 
      max = list.get(key); 
      System.out.println(i + ": " + key + " " + list.get(key)); 
      break; 
     } 
    } 
} 
+0

OK, 난의 LinkedHashMap로 변경,하지만 여전히 문제가 해결되지 않습니다. – fedorp1

+0

모든 값을보고 상위 3 개를 찾고 값을 출력하려고합니까? – Ascalonian

+0

현재 어떻게 인쇄 중인지 예를 들려 줄 수 있습니까? –

답변

2

이 양식에 프로그램을 수정할 수 :

for (int i = 1; i <= 3; i++) { 
    int max = -1; 
    Character maxKey = 'a'; 
    for (Character key : list.keySet()) { 
     if (list.get(key) > max) { 
      max = list.get(key); 
      maxKey = key; 
     } 
    } 
    System.out.println(i + ": " + maxKey + " " + max); 
    list.remove(maxKey); 
} 
+0

@JeanLogeart를 볼 수 있습니다. 그 문제에 대한 답은 멋지게 빛나지 않습니다. 정말 좋은 해결책은'PriorityQueue' 클래스를 기반으로합니다.이 클래스는 힙 데이터 구조를 사용하여이 문제에 자연스럽게 부합합니다. –

+0

O (n log n)의 키를 비교하여 정렬 -이 솔루션은 O (n)입니다. 단 24 개의 키 (문자 수)가 있으므로 정렬과 톱 3을 취하는 것이 반복에 비해 3 배 빠를 것입니다. 반면에 3 반복을 없앨 수는 있지만 훨씬 더 복잡 할 것입니다. 나는 그것이 이상하지만 직감에 대해 주장하지 않는다 : 나는 그것이 간단하다고 생각한다. – baju

+0

@MarkoTopolnik 당신 말이 맞습니다 - 정말 좋을 것입니다. – baju

8

+0

Upvoted. 기본적으로 동일한 단계를 수행하는 Java 7- 상세 답변에 대해서는 내 대답 –

0

당신은 상위 3 회 발생 수를 기준으로 항목을 정렬하고 얻을 필요가 :

List<Entry<Character, Integer>> entryList = new ArrayList<>(list.entrySet()); 
Collections.sort(entryList, new Comparator<Entry<Character, Integer>>(){ 
    @Override 
    public int compare(Entry<Character, Integer> e1, Entry<Character, Integer> e2) { 
     return e2.getValue() - e1.getValue(); // descending order 
    } 
}); 

// now let's get the top 3 
List<Character> top3 = new ArrayList<>(3); 
for(Entry<Character, Integer> e : entryList) { 
    top3.add(e.getValue()); 
    if(top3.size() == 3) { 
     break; 
    } 
} 
0

여기 자바 8 스트림을 사용하여 솔루션입니다, @assylias에서 제공 한 것을 기반으로합니다. String에서 Map으로 문자 수를 수집하고 상위 3 개 항목을 선택하는 작업을 수행합니다.

import java.util.ArrayList; 
import static java.util.Comparator.*; 
import java.util.List; 
import java.util.Map.Entry; 
import static java.util.stream.Collectors.*; 

public class Stream { 

    public static void main(final String[] args) { 
     final String text = "hello stackoverflow, let's count these character occurrences!"; 
     final char[] charArray = text.toCharArray(); 
     final List<Character> characters = new ArrayList<Character>(text.length()); 
     for (final char c : charArray) { 
      characters.add(c); 
     } 

     final List<Entry<Character, Long>> top3 = characters.stream() 
       .collect(groupingBy(Character::charValue, counting())) 
       .entrySet().stream() 
       .sorted(comparing(Entry::getValue, reverseOrder())).limit(3).collect(toList()); 

     System.out.println(top3); 
    } 
} 

는 출력 :

[e=8, c=7, =6] 
+0

세부 사항 : 그러나 'ArrayList'에 넣으려는 요소의 수를 알면 왜 'ArrayList'를 적절한 크기로 초기화하지 않고 크기를 없앨 수 있습니까? – baju

+0

크기를 미리 알지 못합니다. 문자열에는 100 만 개가 넘는 UTF-8 문자 중 하나가 포함될 수 있지만 일반적으로 훨씬 적은 문자가 포함됩니다. –

+0

흠,하지만 귀하의 예제에서 당신은 문자의 배열을 반복하고 있습니까? 배열의 크기를 알 수 있습니다. 결과적으로'character'리스트를 적절한 크기로 초기화 할 수 있습니다. 내가 잘못? – baju

관련 문제