Java에서 종종 발생하는 문제 (일반적으로 전산 언어 코드 작성 중)는 데이터 세트의 일부 항목 발생 횟수를 계산 한 다음 해당 횟수로 항목을 정렬해야합니다. 가장 간단한 예는 단어 계산입니다. 텍스트 파일에서 각 단어의 발생 횟수를 계산 한 다음, 가장 자주 사용되는 단어를 찾기 위해 단어 수를 정렬해야합니다.개수를 유지하기위한 인덱스가있는 PriorityQueue
불행히도 Java는이 작업에 적합한 데이터 구조를 갖고 있지 않습니다. 내가 계산할 때 컬렉션의 인덱스로 단어를 사용해야하므로 단어를 읽을 때마다 올바른 카운터를 효율적으로 찾아 볼 수 있지만 정렬하려는 값은 카운트가 아니라 숫자입니다. 말.
Map<String, Integer>
은 단어와 관련된 수를 찾는 데 필요한 인터페이스를 제공하지만지도는 키 (예 : TreeMap
)로만 정렬 할 수 있습니다. PriorityQueue
은 당신이 제공하는 비교기를 정렬 할 수있는 좋은 힙 구현이지만 어떤 종류의 인덱스로 요소에 액세스 할 수있는 방법이 없으며 요소를 업데이트하고 다시 heapify 할 수 없습니다 (제거 및 추가를 제외하고) . 단일 유형 매개 변수를 사용하면 단어와 카운트를 함께 사용하여 하나의 객체로 묶어야합니다.
Map<String, Integer> wordCounts = countStuff();
PriorityQueue<NamedCount> sortedCounts = new PriorityQueue<>(wordCounts.size(),
Collections.reverseOrder());
for(Entry<String, Integer> count : wordCounts.entrySet()) {
sortedCounts.add(new NamedCount(count.getKey(), count.getValue()));
}
(NamedCount
는 단순한 pair<string, int>
구현하는 것을 주 :
내 현재 "솔루션"은 다음을 정렬 할 PriorityQueue
로 모두 복사를 계산하는 동안지도의 수를 저장하는 것입니다 Comparable
)를 사용하여 정수를 비교하십시오. 그러나 이것은 비효율적입니다. 특히 데이터 세트가 매우 커질 수 있고 메모리에 두 세트의 카운트 세트를 유지하는 것이 낭비입니다.
PriorityQueue
안에있는 객체에 무작위로 액세스 할 수있는 방법이 있습니까? 그렇다면 PriorityQueue에 하나의 복사본을 저장하고 업데이트 할 때 다시 복사 할 수 있습니까? PriorityQueue<NamedCount>
에있는 객체에 "포인터"를 유지하는 Map<String, NamedCount>
을 사용하는 것이 합리적입니까?
,가 'Stream'에있는 시설들 – fge
왜 NamedCount를 바로 사용하고'Map'를 매핑하지 않습니까? 이렇게하면 getValues ()를 Collection으로 사용하고 정렬 할 수 있습니다. –
laune
@laune 간단하다. 기본 Java 7 라이브러리 만 사용하는 좋은 솔루션처럼 들린다. 마크 피터스 (Mark Peters)와 동의하는 경향이 있지만, '멀티 세트 (Multiset)'는 개념적으로 더 깨끗한 디자인이다. – Edward