如何查询数组中的范围并打印数组中 [xth, x + yth] 最频繁的整数?

How to query a range in an array and print the [xth, x + yth] most frequent integers in the array?

假设一些任意的整数数组,例如 [3, 1, 1, 1, 13, 13, 13, 13, 13, 8, 8, 8, 8, 8, 8](顺序无关紧要,我刚刚订购了它们以便更容易阅读)

我如何着手创建一个方法,当询问范围时,比如 [2,4],打印给定数组中第二多、第三多和第四多的整数?在此示例数组中,它将按频率顺序打印: 值:13。频率:5 值:1。频率:3 值:3。频率:1

注意整数 8 是最常见的整数,而 3 是第 4 个最常见的整数。

public static void main(String[] args) {
    SomeClass obj = new SomeClass();
    obj.printRange(new int[]{2, 4}, new int[]{1, 1, 1, 3, 4, 4, 8, 8});
}

public void printRange(int[] range, int[] arrayOfNumber) {
    // Using HashMap so we can save frequency against each number
    HashMap<Integer, Integer> hashMap = new HashMap<>();
    for (int i = 0; i < arrayOfNumber.length; i++) {
        if (hashMap.get(arrayOfNumber[i]) != null) {
            hashMap.put(arrayOfNumber[i], hashMap.get(arrayOfNumber[i]) + 1);
        } else {
            hashMap.put(arrayOfNumber[i], 1);
        }
    }

    //Sort the hashmap and convert it to linkedhashmap
    LinkedHashMap<Integer, Integer> linkedHashMap = sortHashMapByValues(hashMap);
    Iterator<Map.Entry<Integer, Integer>> itr = linkedHashMap.entrySet().iterator();
    //iterate through the linkedhashmap
    for (int i = 0; i < range[1]; i++) {
        // print only your range: expecting range in array → [2,4]
        // start with range[0]→2, range[1]→4
        if (i >= range[0] && itr.hasNext()) {
            Map.Entry<Integer, Integer> entry = itr.next();
            System.out.println("Range at: " + i);
            System.out.println("key: " + entry.getKey());
            System.out.println("Frequency: " + entry.getValue());
        }
    }
}

public LinkedHashMap<Integer, Integer> sortHashMapByValues(
    HashMap<Integer, Integer> passedMap) {
    List<Integer> mapKeys = new ArrayList<>(passedMap.keySet());
    List<Integer> mapValues = new ArrayList<>(passedMap.values());
    Collections.sort(mapValues);
    Collections.sort(mapKeys);

    LinkedHashMap<Integer, Integer> sortedMap =
        new LinkedHashMap<>();

    Iterator<Integer> valueIt = mapValues.iterator();
    while (valueIt.hasNext()) {
        int val = valueIt.next();
        Iterator<Integer> keyIt = mapKeys.iterator();

        while (keyIt.hasNext()) {
            Integer key = keyIt.next();
            int comp1 = passedMap.get(key);
            int comp2 = val;

            if (comp1 == comp2) {
                keyIt.remove();
                sortedMap.put(key, val);
                break;
            }
        }
    }
    return sortedMap;
}

你想先用所有整数填充一个映射,其中每个整数是键,频率是值。如果遇到现有整数,则增加频率(值)。

然后您可以根据条目的值(频率)对该映射中的条目进行排序,并将结果简单地放入列表中。

现在你有一个排序的条目集列表,其中键是整数,值是频率,你可以简单地通过索引访问它:

public static void main(final String[] args) {
    final int integers[] = new int[] {3, 1, 1, 1, 13, 13, 13, 13, 13, 8, 8, 8, 8, 8, 8};

    final Map<Integer, Integer> integerFrequencies = new HashMap<>();

    // Create a map of all integers with their frequency:
    for (final int i : integers) {
        if (integerFrequencies.containsKey(i)) {
            integerFrequencies.put(i, integerFrequencies.get(i) + 1);
        }
        else {
            integerFrequencies.put(i, 1);
        }
    }

    // Sort the map entries by their value (frequency) into a list:
    final var integerFrequenciesSorted = integerFrequencies.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).collect(Collectors.toList());

    // Print 2nd to 4th entry:
    for (int i = 1; i < 4; i++) {
        final var integerFrequency = integerFrequenciesSorted.get(i);
        System.out.println("Value: " + integerFrequency.getKey() + ". Frequency: " +  integerFrequency.getValue());
    }
}

打印:

Value: 13. Frequency: 5
Value: 1. Frequency: 3
Value: 3. Frequency: 1