如何按降序打印特定字符串的出现次数?

How to print amount of occurrences of specific string in descending order?

我希望使用 String[] 日志详细说明已连接到网站的用户,以降序打印出每个用户连接的次数。每个日志都包含一些信息,但唯一的用户 ID 始终在数组的第一个索引内。

我试图在 O(N) 时间内遍历数组,通过将每个用户连接到 HashMap 来计算每个用户连接了多少次,然后根据连接次数降序打印出连接的用户他们有联系。如何才能做到这一点?如果有更简单的方法来跟踪 String[] 中出现的次数,我愿意改变我的整个实现。我在下面附上了一个例子:

 // Connection logs in the form [Username, Location, time]
String[] logs = {
    "name1,Chicago,8pm",
    "name2,New York,6pm",
    "name3,Los Angeles,2am",
    "name1,Chicago,3pm",
    "name1,Chicago,12pm",
    "name4,Miami,3pm"
    "name4,Miami,6pm"
};

printConnections(logs);

/* Desired output:
    name1: 3
    name2: 2
    name4: 2
    name3: 1
*/

public static void printConnections(String[] connections){
    HashMap<String, Integer> hashmap = new HashMap<String, Integer>();
    for (String log : connections){
        String name = log.split(",")[0];
        if (hashmap.containsKey(name)){
            hashmap.replace(name, hashmap.get(name) + 1);
        }
        else{
            hashmap.put(name, 1);
        }
    }
    // Print all key/values in descending order of value
}

TLDR:

// Print all key/values in descending order of value
var sorted = hashmap.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()));
sorted.forEach(pair->System.out.println(pair.getKey() + ": " + pair.getValue()));

输出:

name1: 3
name4: 2
name3: 1
name2: 1

如何运作?

hashmap.entrySet() 将 return 一组 Map.Entry 个对象 .stream() 将 return 这些对象的流 .sorted() 将根据 Map.Entry 个对象的值对流进行排序

已满:

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;

public class Main {

    public static void printConnections(String[] connections) {
        HashMap<String, Integer> hashmap = new HashMap<String, Integer>();
        for (String log : connections) {
            String name = log.split(",")[0];
            if (hashmap.containsKey(name)) {
                hashmap.replace(name, hashmap.get(name) + 1);
            } else {
                hashmap.put(name, 1);
            }
        }
        // Print all key/values in descending order of value
        var sorted = hashmap.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()));
        sorted.forEach(pair->System.out.println(pair.getKey() + ": " + pair.getValue()));
    }

    public static void main(String[] args) {

        // Connection logs in the form [Username, Location, time]
        String[] logs = {
                "name1,Chicago,8pm",
                "name2,New York,6pm",
                "name3,Los Angeles,2am",
                "name1,Chicago,3pm",
                "name1,Chicago,12pm",
                "name4,Miami,3pm",
                "name4,Miami,6pm"
        };

        printConnections(logs);
    }
}

首先,我假设 O(n) 是指 O(n),其中 n = 唯一用户数(即 hashmap.keySet().size())。不幸的是,您的问题涉及最多 O(n*log(n)) 复杂度的排序,因此我认为不可能在 O(n) 时间内完成此操作。但是,我仍然有一些代码可以完成工作:

ArrayList<Entry<String, Integer>> logList = new ArrayList<>(hashMap.entrySet());
Collections.sort(logList, new Comparator<Entry<String, Integer>>() {
    @Override
    public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
        return o2.getKey().compareTo(o1.getKey());
    }
});

你必须使用 Java Stream Api 来解决这个问题。

hashmap.entrySet()
       .stream()
       // "Map.Entry.comparingByValue())" is convert HashMap value into ascending order by default
       // "Collections.reverseOrder()" is convert HashMap value into reverse of ascending order(descending)
       .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
       // print the hashmap
       .forEach(entry -> System.out.println(entry.getKey()  + ": " + entry.getValue()));