笔试编程题:输入一个英文句子,输出重复的字母(不包括空格)和重复次数,结果按次数倒序(从大到小)排列。例如,输入“I am a student”,输出 a 2 t 2。

题目:

输入一个英文句子,输出重复的字母(不包括空格)和重复次数,
结果按次数倒序(从大到小)排列。
例如,输入“I am a student”,输出 a 2 t 2。

分析

要点有两个:

  1. 统计字符即次数
    - 我使用了两种方法来统计次数 ,如下:
    1. 利用Map<Character, Integer>,存放字符及其出现次数
    2. 先将字符排序,再用两个指针一前一后,得出字符的出现次数
  2. 按次数倒序排列(从大到小)
    - 如果是顺序,直接使用Arrays.sort()即可,但题目要求是倒序,所以考虑自定义比较器Comparator

解题:

package com.guo.bishi;

import java.util.*;

/**
 * @Author FireLightGuo
 * @Date 2021/10/29 21:15
 * 题目:输入一个英文句子,输出重复的字母(不包括空格)和重复次数,
 *     结果按次数倒序(从大到小)排列。
 *     例如,输入“I am a student”,输出 a 2 t 2。
 **/
public class PrintRepeatedCharAndCount {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String sentence = sc.nextLine();

        resolveByMap(sentence);
        resolveByList(sentence);
    }

    // 解法1:使用Map
    public static void resolveByMap(String sentence) {
        sentence = sentence.replace(" ", ""); // 去掉空格
        char[] chars =  sentence.toCharArray(); // 转化为字符数组

        //Map<Integer, Character> resultMap = new TreeMap<>(); // 错误,同样次数的字符会被覆盖, 因为key相同
        Map<Character, Integer> resultMap = new HashMap<>();

        for (char c : chars) {
            if (resultMap.containsKey(c)) {
                resultMap.put(c, resultMap.get(c) + 1);
            } else {
                resultMap.put(c, 1);
            }
        }

		// 筛选出重复次数大于1的Entry,存放到list中,再对list进行逆序排序
        List<Map.Entry<Character, Integer>> list = new ArrayList<>();
        for (Map.Entry<Character, Integer> entry : resultMap.entrySet()) {
            if (entry.getValue() > 1) list.add(entry); // 题目要的是重复次数大于1的字符
        }

        // 自定义Comparator接口的匿名内部类,实现倒序排列
        list.sort(new Comparator<Map.Entry<Character, Integer>>() {
            @Override
            public int compare(Map.Entry<Character, Integer> o1, Map.Entry<Character, Integer> o2) {
                int count1 = o1.getValue();
                int count2 = o2.getValue();
                return count2 - count1; // ==>  -(count1 - count2)
            }
        });

        System.out.println(list);
    }

    // 解法2:使用List
    public static void resolveByList(String sentence) {
        sentence = sentence.replace(" ", ""); // 去掉空格
        char[] chars = sentence.toCharArray(); // 转化为字符数组
        Arrays.sort(chars); // 字符排序,方便统计重复次数


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

        int count = 1; // 重复次数,初始为1

		// 统计次数的核心代码,前后指针i,j,(注意这里的chars是排好序的)
		// 如:my name is stephen curry
		// 去掉空格,排序后:aceeehimmnnprrsstuyy
        for (int i = 0, j = 1; j < chars.length; i++, j++) {
            if (chars[i] == chars[j]) {
                count++;
            } else if (count > 1) { // 重复次数大于1,添加到list中
                // 字符拼接为字符串,格式为 次数 + 字符,
                // 如e出现了12次,则添加"12e"到list中
                // 注意这里的 ""+ ,如果直接count+chars[i]得到的是整数
                resultList.add("" + count + chars[i]); // eg: 2a, 3c, 14f ...
                count = 1;
            }
        }

        resultList.sort(new descComparator()); // 自定义递减排列器
		
        for (String str : resultList) {
        // 截取字符及对应次数,如"126a", 即字符a,出现次数126
        // str.charAt(str.length()-1)截取字符
        // str.substring(0,str.length()-1)截取次数
            System.out.print(str.charAt(str.length()-1) + " " +
                    str.substring(0,str.length()-1) + " ");
        }
    }
    
    static class descComparator implements Comparator<String> {
        @Override
        public int compare(String o1, String o2) {
            int count1 = Integer.parseInt(o1.substring(0, o1.length()-1));
            int count2 = Integer.parseInt(o2.substring(0, o2.length()-1));
            return count2 - count1;
        }
    }

}

总结

这道题是笔试的一道编程题,难度不大,但当时有一些细节没注意到,现在把这道题解出来了,算是弥补了这个遗憾。
希望对大家有帮助

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值