查找字符串中,出现最先出现最多的字符

2019-02-18  本文已影响0人  Mr_UU

查找字符串中,出现最先出现最多的字符

查找字符串中最先出现次数最多的字符。首先需要查找出现次数最多的字符串,然后查找最多的字符串中出现最早的哪一个字符。
分析:遍历字符串即可统计到各个字符出现的次数;统计最早且最多的字符时,一般有两种思路:

  1. 使用map,遍历两边。第一遍,遍历字符串数组, 统计各个字符出现的次数,并记录出现最多的次数N;第二遍,遍历字符串,从map中获取字符出现次数,找到第一个出现次数为N的字符。
public static char cal2(String str) {
    Map<Character,Integer> map = new HashMap<>(MAX_CHAR_INT);
    char[] ch = str.toCharArray();
    for (int i = 0;i<ch.length;i++) {
        if(map.containsKey(ch[i])){
            map.put(ch[i],map.get(ch[i])+1);
        }else {
            map.put(ch[i],1);
        }
    }
    int index = -1 ;
    char maxChar = ch[0];
    for(int i = 0 ;i<ch.length;i++){
        if(map.get(ch[i]) > index ){
            index = map.get(ch[i]);
            maxChar = ch[i] ;
        }
    }
    return maxChar;
}
  1. 使用map,逆序遍历一次。逆序遍历字符数组,记录出现次数最多的字符C和最多次数N,由于是逆序遍历,最后记录到的字符就是最早出现且出现次数最多的字符。

public static char cal3(String str) {
    Map<Character,Integer> map = new HashMap<>(MAX_CHAR_INT);
    char[] ch = str.toCharArray();
    int max = 0 ;
    char res = ch[0] ;
    for (int i = ch.length -1 ; i >= 0;i --) {
        if(map.containsKey(ch[i])){
            map.put(ch[i],map.get(ch[i])+1);
            if(map.get(ch[i]) >= max ){
                max = map.get(ch[i]);
                res = ch[i] ;
            }
        }else {
            map.put(ch[i],1);
        }
    }
    return res ;
}
  1. 使用数组。首先字符的个数是有限的(Character.MAX_VALUE-1个),可以使用数组,使数组的每个下标对应一个字符(char和int可以相互抓换),基于这一点可以使用数组nums来记录各个字符出现的次数,使用orders数组记录各个字符出现的顺序(字符出现次数为0时表示第一次出现,此时将该字符记录在orders数组最后)。
    执行步骤:
 public static Character findFirstMaxChar(@NonNull String str){
        int indx = 0;
        char[] orders = new char[MAX_CHAR_INT];
        int[] nums = new int[MAX_CHAR_INT];
        for(int i = 0, len = str.length(); i < len; i ++){
            char c = str.charAt(i);
            if(nums[c] > 0){
                nums[c] = nums[c] + 1;
            } else {
                nums[c] = 1;
                orders[indx ++] = c;
            }
        }
        //find max num
        int max = 0, maxIndx = 0;
        for (int i = 0; i < nums.length; i++) {
            if( max < nums[i] ){
                max = nums[i];
                maxIndx = i;
            }
        }
        // find first max num char
        int minIndx = orders.length-1;
        for(int i = maxIndx; i < nums.length; i ++){
            if(nums[i] < max){
                continue;
            }
            for (int j = 0; j < minIndx; j++) {
                if( i != (int) orders[j]){
                    continue;
                }
                if(minIndx > j){
                    minIndx = j;
                }
                break;
            }
        }
//        System.out.println(String.format("最先出现最多的字符是:'%c',出现次数:%d", orders[minIndx], max));
        return orders[minIndx];
    }
  1. 基于第二种方法的思想,对第三种方法优化。对字符串倒序遍历,遍历一次,记录各个字符出现次数,并记录最大出现次数,及最大次数是的下标。由于是从后往前遍历,记录到最后一个出现最多次数的字符就是最早出现且出现最多的字符。须注意一点,须判断当前字符出现次数大于等于最多次数时,更新最多次数字符及下标时。
public static Character findFirstMaxChar0(@NonNull String str){
        int[] nums = new int[MAX_CHAR_INT];
        int maxN = 0;
        char maxC = str.charAt(0);
        for(int i = str.length() - 1; i >= 0; i --){
            char c = str.charAt(i);
            if(nums[c] > 0){
                nums[c] = nums[c] + 1;
            } else {
                nums[c] = 1;
            }
            if(nums[c] >= maxN){
                maxN = nums[c];
                maxC = c;
            }
        }
//        System.out.println(String.format("最先出现最多的字符是:'%c',出现次数:%d", maxC, maxN));
        return maxC;
    }

各个方法运行100次的平均运行时间对比如下图所示。

N表示字符串长度,一下时间都是每个方法运行100次得到的平均时间,单位毫秒


两种使用数组的方法运行时间对比 四种方法运行时间对比

结论:

上一篇下一篇

猜你喜欢

热点阅读