Bitte sortieren Sie bei gegebener Zeichenfolge die Zeichen in der Zeichenfolge in absteigender Reihenfolge der Häufigkeit ihres Auftretens

package com.example.demo;

import java.util.*;

public class Deni {
    public static void main(String[] args) {
        String s = "aaffaawnnnwqqqoooooooqrrrrllllllllllrd";
        char[] chars = s.toCharArray();
        // 使用map统计字符出现的个数
        HashMap<Character, Integer> map = countCharMap(chars);
        Integer[] objects = map.values().toArray(new Integer[0]);
        // 首先排序
        quickSort(objects, 0, objects.length - 1);
        // 然后按照从大到小排序顺序组装字符
        combineCharBySort(chars, map, objects);
        // 打印组装好的字符
        for (int i = 0; i < chars.length; i++) {
            System.out.print(chars[i]);
        }
        System.out.println();
    }

    /**
     * 使用map统计字符出现的次数
     * @param chars 字符数组
     * @return map
     */
    private static HashMap<Character, Integer> countCharMap(char[] chars) {
        HashMap<Character, Integer> map = new HashMap();
        for (char aChar : chars) {
            if (map.get(aChar) == null) {
                map.put(aChar, 1);
            }else{
                map.put(aChar, map.get(aChar) + 1);
            }
        }
        return map;
    }

    /**
     * 组装要打印的字符数组
     * @param chars 字符数组
     * @param map map
     * @param objects 从大到小排序好的每个字符出现的个数
     */
    private static void combineCharBySort(char[] chars, HashMap<Character, Integer> map, Integer[] objects) {
        // 要存入的字符串下标
        int j = 0;
        for (int i = 0; i < objects.length - 1; i++) {
            for (Map.Entry<Character, Integer> characterIntegerEntry : map.entrySet()) {
                Character key = characterIntegerEntry.getKey();
                Integer value = characterIntegerEntry.getValue();
                if (value.equals(objects[i])) {
                    int count = j;
                    // 将当前相同的字符挨个存入数组
                    while (j - count < value) {
                        chars[j++] = key;
                    }
                    // 遍历过的字符从map中移除,降低遍历次数
                    map.remove(key);
                    break;
                }
            }

        }
    }

    /**
     * 快速排序
     * @param arr 数组
     * @param left 数组左下标
     * @param right 数组右下标
     */
    private static void quickSort(Integer[] arr, int left, int right){
        if (left >= right) {
            return;
        }
        // 排序并获取中间值(基准值)的下标
//        int mid = getMid(arr, left, right);
        int mid = getMid2(arr, left, right);
        // 递归排序左边的区间,注意:最后一位参数不能写成mid,否则会死循环
        quickSort(arr, left, mid - 1);
        // 递归排序右边的区间,中间的参数不能写为mid,否则会死循环
        quickSort(arr, mid + 1, right);

    }

   


    /**
     * 查找基准下标(巧妙使用数组下标排序)
     * @param arr 数组
     * @param left 左下标
     * @param right 右下标
     * @return 中值下标
     */
    private static int getMid2(Integer[] arr, int left, int right){
        int i = left;
        int pivot = arr[right];
        for (int j = left; j < right; j++) {
            if (arr[j] > pivot) {
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
                i++;
            }
        }
        int temp = arr[i];
        arr[i] = arr[right];
        arr[right] = temp;
        return i;
    }


    /**
     * 查到基准下标(排序)
     * @param arr 数组
     * @param left 数组左下标
     * @param right 数组右下标
     * @return 中值下标
     */
    private static int getMid(Integer[] arr, int left, int right) {
        int base = arr[left];
        while (left < right){
            // 从最右边开始查找小于基准点点值,如没有就将最右边的下标减1
            // (注意:判断条件必须是包含等于,否吃会死循环,因此快速排序不能保证两个等值的元素,排完循序后还保持原有循序,不是稳定的排序算法)
            while (left < right && arr[right] >= base) {
                right--;
            }
            // 找到小于基准点点值后交换
            arr[left] = arr[right];
            // 从左边开始查找大于基准值的元素,没有就将下标加1
            while (left < right && arr[left] <= base){
                left++;
            }
            // 找到大于基准点的值后交换
            arr[right] = arr[left];
        }
        // 最后将原来的基准值填充回来,此时的left就是基准值的下标(注意:left经过++操作已经不是原来的下标值了)
        arr[left] = base;
        return left;
    }

}

おすすめ

転載: blog.csdn.net/bingxuesiyang/article/details/103653346