簡體   English   中英

如何從hashmap中獲取5個最高值?

[英]How to get 5 highest values from a hashmap?

我有一個Hashmap鏈接存儲為鍵的zipcodes和作為值存儲在hashmap中的填充。

hashmap包含大約33k個條目。

我試圖從5個郵政編碼中獲取5個最高人口值,並打印出與5個最高人口相關聯的5個郵政編碼,但我無法理解如何做到這一點的算法。

如果它只是一個,它很容易,但5限制給我一些麻煩。

我知道將5個值存儲在一個int數組中,我有一個計數器來確定它們中何時存儲了5個,但就是這樣。

謝謝

    int populatedCounter = 0;

    int[] populatedZip = new int[5];

    it = zipCodePop.entrySet().iterator();
    while (it.hasNext())
    {
        Map.Entry pairs = (Map.Entry)it.next();

        for (int i = 0; i < populatedZip.length; i++)
        {

        }
    }

}

將這樣的集合的條目放入列表並對其進行排序是一種選擇。 但33k元素是一個數字,其中排序的O(n * log(n))復雜性可能已經具有顯着的性能影響。

一個apporach將是使用nr4bt已經提到過的PriorityQueue(我回答時寫了這個片段)。 它基本上將所有元素插入到PriorityQueue中,該PriorityQueue根據映射條目的值進行排序。

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.PriorityQueue;

public class GreatestOfMap
{
    public static void main(String[] args)
    {
        Map<String, Integer> map = new HashMap<String, Integer>();

        map.put("zip000", 1234);
        map.put("zip001", 2345);
        map.put("zip002", 3456);
        map.put("zip003", 4567);
        map.put("zip004", 5678);
        map.put("zip005", 6789);
        map.put("zip006", 123);
        map.put("zip007", 234);
        map.put("zip008", 456);
        map.put("zip009", 567);
        map.put("zip010", 7890);
        map.put("zip011", 678);
        map.put("zip012", 789);
        map.put("zip013", 890);

        int n = 5;
        List<Entry<String, Integer>> greatest = findGreatest(map, 5);
        System.out.println("Top "+n+" entries:");
        for (Entry<String, Integer> entry : greatest)
        {
            System.out.println(entry);
        }
    }

    private static <K, V extends Comparable<? super V>> List<Entry<K, V>> 
        findGreatest(Map<K, V> map, int n)
    {
        Comparator<? super Entry<K, V>> comparator = 
            new Comparator<Entry<K, V>>()
        {
            @Override
            public int compare(Entry<K, V> e0, Entry<K, V> e1)
            {
                V v0 = e0.getValue();
                V v1 = e1.getValue();
                return v0.compareTo(v1);
            }
        };
        PriorityQueue<Entry<K, V>> highest = 
            new PriorityQueue<Entry<K,V>>(n, comparator);
        for (Entry<K, V> entry : map.entrySet())
        {
            highest.offer(entry);
            while (highest.size() > n)
            {
                highest.poll();
            }
        }

        List<Entry<K, V>> result = new ArrayList<Map.Entry<K,V>>();
        while (highest.size() > 0)
        {
            result.add(highest.poll());
        }
        return result;
    }
}

嘗試使用標准方法並假設人口計數在HashMap存儲為Integer

List<Integer> list = new ArrayList<Integer>(zipCodePop.values());
Collections.sort(list, Collections.reverseOrder());
List<Integer> top5 = list.subList(0, 5);

public class CheckHighiestValue {public static void main(String ... s){

    HashMap<String, Integer> map = new HashMap<String, Integer>();

    map.put("first", 10000);
    map.put("second", 20000);
    map.put("third", 300);
    map.put("fourth", 800012);
    map.put("fifth", 5000);
    map.put("sixth", 30012);
    map.put("seventh", 1234);
    map.put("eighth", 45321);
    map.put("nineth", 5678);

    Set<Entry<String, Integer>> set = map.entrySet();

    List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(
            set);

    Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {

        @Override
        public int compare(Entry<String, Integer> o1,
                Entry<String, Integer> o2) {

            return o2.getValue().compareTo(o1.getValue());
        }

    });
    System.out.println(list.subList(0, 5));
}

}

PriorityQueue也會有所幫助,也是一個關於如何從列表中獲得前k個的好主題,您可以查看此鏈接

PriorityQueue<Integer> p = new PriorityQueue<Integer>(5);

int[] a = new int[]{3,5,10,1,23,42,66,1333,545,110};

for (int i : a){
    p.add(i);
    if (p.size() > 5){
        p.poll();
    }
}

//output will be highest 5, [42, 66, 110, 1333, 545]

你可以有O(n log(k))時間復雜度// k是你的最高值。

這是我做的,希望能為您提供您想要使用的東西。

public class TopsCollection { 

private static Map<String, Integer> collectors = new HashMap<>();

public TopsCollection() {
}

public void add(String playerName, int score) {
    collectors.put(playerName, score);
}

public void clearCollectors() {
    synchronized (collectors) {
        collectors.clear();
    }
}

public List<Map.Entry<String, Integer>> getTops() {
    return collectors.entrySet().stream().sorted(comparing(Map.Entry::getValue, reverseOrder())).limit(5).collect(toList());
}

public int getTopByName(String name) {
    for (int i = 0; i < getTops().size(); i++) {
        if (getTops().get(i).getKey().contains(name)) {
            return i;
        }
    }
    return 0;
}

getTopByName允許您獲取指定名稱的頂部位置。

如果沒有電腦,只用一張紙和一支鉛筆,你會怎么做? 假裝你有一堆索引卡上有數字,找到5個最高數字是你的工作。 你會怎么做? 寫下其他人可以遵循的步驟來實現目標,當你寫完這些步驟時,你將有一個算法,你可以開始考慮用代碼實現。

你說一個單一的最大值很容易,所以它就像你用一個最大值一樣,但是要跟蹤五個最大值。 這里有一組最大值可能會有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM