[Android] [Algorithm] Implement a list of the top ten room names from a pile of room name data, and the first item must be the one with the latest name and the largest number.

background

The customer has such a requirement:
There are a bunch of room names with different names in a room list, but there are always several room names with the same name. Then display the top ten data with the same name in the current room list in an Adapter.

then it means that a data structure with a length of 10 needs to be constructed, which contains at least the room name and the number of the same room name.
Then you have to traverse the entire original room name data. To put it simply: it is a list, and the list contains various names.

What the customer wants is the room names with the top ten most frequent name occurrences.

Ideas

Algorithm implementation:

  • It is necessary to create a kv pair or hash table to store the current name and its corresponding number;

This implementation is relatively simple. It just traverses the entire room name. If there is an increase, put it in; otherwise, ignore it.

  // 遍历获取数据
        for (RoomInfo roomInfo : roomList) {
    
    
            String roomName = roomInfo.getSubject();
            // 添加 前缀展示
            String roomNameWithPremix = RoomNameListAdapter.ROOM_PREMIX + roomName;
            if (roomNameCountMap.containsKey(roomNameWithPremix)) {
    
    
                int count = roomNameCountMap.get(roomNameWithPremix);
                count++;
                roomNameCountMap.put(roomNameWithPremix, count);
            } else {
    
    
                roomNameCountMap.put(roomNameWithPremix, 1);
            }
        }

This is also my first time to use this object, and there is still a lot I don’t understand.
For details, please refer to the official documentationInsert image description here

The key point is the type of comparator:
Insert image description here

PriorityQueue<RoomNameCountPair> queue = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
    
    
            queue = new PriorityQueue<>(Comparator.comparingInt(RoomNameCountPair::getCount));
        }

Among::Can be used forReference. Insert image description here

  • final code

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

    List<String> subjectWithTopTen = new ArrayList<>();

    private List<String> getTopRoomNameList(List<RoomInfo> roomList, int limit) {
    
    
        // 重新刷
        roomNameCountMap.clear();
        subjectWithTopTen.clear();
        if (roomList.isEmpty()) {
    
    
            return subjectWithTopTen;
        }
        // 遍历获取数据
        for (RoomInfo roomInfo : roomList) {
    
    
            String roomName = roomInfo.getSubject();
            // 添加 前缀展示
            String roomNameWithPremix = RoomNameListAdapter.ROOM_PREMIX + roomName;
            if (roomNameCountMap.containsKey(roomNameWithPremix)) {
    
    
                int count = roomNameCountMap.get(roomNameWithPremix);
                count++;
                roomNameCountMap.put(roomNameWithPremix, count);
            } else {
    
    
                roomNameCountMap.put(roomNameWithPremix, 1);
            }
        }

        // 优先队列 queue 来对房间名称出现次数进行排序
        PriorityQueue<RoomNameCountPair> queue = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
    
    
            queue = new PriorityQueue<>(Comparator.comparingInt(RoomNameCountPair::getCount));
        }

        for (Map.Entry<String, Integer> entry : roomNameCountMap.entrySet()) {
    
    
            queue.offer(new RoomNameCountPair(entry.getKey(), entry.getValue()));
            // 是否大于限制的10个,如果是就弹出最高优先级的
            if (queue.size() > limit) {
    
    
                queue.poll();
            }
        }

        while (!queue.isEmpty()) {
    
    
            subjectWithTopTen.add(0, queue.poll().getRoomName());
        }

        return subjectWithTopTen;
    }

How to understand PriorityQueue

Suppose we have the following mock data:

roomNameCountMap = {
  "room1": 5,
  "room2": 3,
  "room3": 2,
  "room4": 7,
  "room5": 1,
  ...
  // 共有20个键值对
}

During the execution of the code, the content of the actual data in queue will change as follows:

  1. Initial state:queue is empty.
  2. When createsPriorityQueue object, a comparatorComparator.comparingInt(RoomNameCountPair::getCount) is specified, which will be based on RoomNameCountPair object's count attribute to sort.
  3. First loop iteration:
    • Encapsulate "room1" and the corresponding count value 5 into RoomNameCountPair objects and add queue.
    • queue medium content [(room1, 5)].
  4. Second loop iteration:
    • Encapsulate "room2" and the corresponding count value 3 into RoomNameCountPair objects and add queue.
    • queue medium content [(room2, 3), (room1, 5)].
  5. Third loop iteration:
    • Encapsulate "room3" and the corresponding count value 2 into the RoomNameCountPair object and add queue.
    • queue medium content [(room3, 2), (room1, 5), (room2, 3)].
  6. Fourth loop iteration:
    • Encapsulate "room4" and the corresponding count value 7 into RoomNameCountPair objects and add queue.
    • queue medium content [(room3, 2), (room2, 3), (room1, 5), (room4, 7)].
  7. Fifth loop iteration:
    • Encapsulate "room5" and the corresponding count value 1 into the RoomNameCountPair object and add queue.
    • queue medium content [(room5, 1), (room3, 2), (room2, 3), (room1, 5), (room4, 7)].
  8. The next loop iteration will continue to insert elements according to the size of the count value, and when the size of queue exceeds the limit, the element with the smallest count value will be popped out. Finally, the first elements with the largest count value are retained in queue. limit

Since we specified the comparator when creating the PriorityQueue object, the elements in queue will be sorted from small to large according to the count value.

Guess you like

Origin blog.csdn.net/weixin_44002043/article/details/133171392
Recommended