lotus

贵有恒何必三更眠五更起 最无益只怕一日曝十日寒

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

1. 题目

读题

HJ102 字符统计

 

 

考查点

 

这道题的考查点可能是以下几个方面:

  • 字符串的处理和操作,如遍历、分割、拼接等。
  • 数据结构的选择和使用,如数组、字典、列表等。
  • 排序算法的理解和实现,如冒泡排序、选择排序、快速排序等。
  • 编程语言的基本语法和规范,如变量、函数、循环、条件判断等。

2. 解法

有两种解法

  • 使用两个数组
  • 使用map 

这道题还有其他解法,比如:

  • 可以用正则表达式来匹配字符串中的数字和字母,然后用Counter类来统计每个字符出现的次数,最后用sorted函数来按照题目要求的排序规则来输出结果。
  • 可以用ord函数和chr函数来将字符转换为ASCII码和反向转换,然后用一个长度为128的数组来存储每个ASCII码对应的字符出现的次数,最后遍历数组,按照题目要求的排序规则来输出结果。

你可以参考以下网址了解更多关于这些解法的代码示例:

解法一:使用两个数组分别存储字符和频率,然后排序,输出 

思路

  • 创建一个长度为36的整型数组,用来存储每个字符出现的次数。数组的前10个元素对应数字0-9,后26个元素对应字母a-z。
  • 读取输入的字符串,遍历每个字符,根据字符的ASCII码值更新对应的数组元素。
  • 创建一个长度为36的字符数组,用来存储每个字符。数组的前10个元素是数字0-9,后26个元素是字母a-z。
  • 对两个数组进行排序,按照字符出现的次数降序排列,如果次数相同,则按照字符的ASCII码升序排列。
  • 遍历排序后的字符数组,如果对应的次数不为0,则输出该字符。

难点

  • 需要处理多组输入,并且每组输入的字符串长度不一定相同,需要用循环和条件判断来控制输入和输出的流程。
  • 需要对字符串中的不同字符进行统计,同时考虑到字符的ASCII码和出现的次数,需要用合适的数据结构来存储和排序这些信息,比如数组、字典、列表等。
  • 需要按照题目要求的排序规则,即按照次数降序,如果次数相同,则按照ASCII码升序,来输出结果,需要用比较函数或者自定义排序方法来实现。

你可以参考以下网址了解更多关于这道题目的解题思路和代码示例:

代码逻辑

 

具体实现

 

public class HJ102 {

public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println(getCharFrequency(sc.nextLine()));
}

public static String getCharFrequency(String str) {
int[] count = new int[36];
char[] chars = new char[36];
int index = 0;
for (char c : str.toCharArray()) {
if (Character.isDigit(c)) {
index = c - '0';
} else {
index = c - 'a' + 10;
}
count[index] += 1;
chars[index] = c;
}

sort(chars, count);
StringBuffer sb = new StringBuffer();
for (int i = 0; i < chars.length; i++) {
if (count[i] > 0) {
sb.append(chars[i]);
}
}
return sb.toString();
}

public static void sort(char[] chars, int[] count) {
int len = chars.length;
for (int i = 0; i < len; i++) {
for (int j = i + 1; j < len; j++) {
if (count[i] < count[j] || (count[i] == count[j] && chars[i] > chars[j])) {
swap(chars, count, i, j);
}
}
}
}

public static void swap(char[] chars, int[] count, int i, int j) {
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;

int temp2 = count[i];
count[i] = count[j];
count[j] = temp2;
}

}

方法二:使用 map 

解题思路如下:

  • 使用一个循环来处理多组输入,每次读取一行字符串。
  • 使用一个字典(map)来存储每个字符出现的次数,遍历字符串中的每个字符,如果字典中不存在该字符,则将其加入字典并初始化次数为1,否则将其次数加1。
  • 使用一个列表(vector)来存储字典中的键值对,即字符和次数,然后对列表进行排序,排序规则是按照次数降序,如果次数相等,则按照字符的ASCII码升序。
  • 使用一个循环来遍历排序后的列表,输出每个字符。

 

具体实现

import java.util.*;

//定义一个字符统计的类
public class CharCount {
    //定义一个方法,接收一个字符串参数,返回一个排序后的字符列表
    public static List<Map.Entry<Character, Integer>> countChar(String str) {
        //创建一个字典,用来存储每个字符出现的次数
        Map<Character, Integer> map = new HashMap<>();
        //遍历字符串中的每个字符
        for (char c : str.toCharArray()) {
            //如果字典中不存在该字符,就将其加入字典,并初始化次数为1
            if (!map.containsKey(c)) {
                map.put(c, 1);
            } else {
                //否则,将其次数加1
                map.put(c, map.get(c) + 1);
            }
        }
        //创建一个列表,用来存储字典中的键值对
        List<Map.Entry<Character, Integer>> list = new ArrayList<>(map.entrySet());
        //对列表进行排序,按照次数降序,如果次数相等,按照字符的ASCII码升序
        Collections.sort(list, new Comparator<Map.Entry<Character, Integer>>() {
            @Override
            public int compare(Map.Entry<Character, Integer> o1, Map.Entry<Character, Integer> o2) {
                //如果次数不相等,按照次数降序
                if (!o1.getValue().equals(o2.getValue())) {
                    return o2.getValue() - o1.getValue();
                } else {
                    //否则,按照字符的ASCII码升序
                    return o1.getKey() - o2.getKey();
                }
            }
        });
        //返回排序后的列表
        return list;
    }

    //定义主方法,用来测试字符统计的方法
    public static void main(String[] args) {
        //创建一个扫描器,用来读取输入
        Scanner sc = new Scanner(System.in);
        //使用一个循环来处理多组输入,每次读取一行字符串
        while (sc.hasNextLine()) {
            String str = sc.nextLine();
            //调用字符统计的方法,得到排序后的字符列表
            List<Map.Entry<Character, Integer>> list = countChar(str);
            //使用一个循环来遍历列表,输出每个字符
            for (Map.Entry<Character, Integer> entry : list) {
                System.out.print(entry.getKey());
            }
            System.out.println(); //换行
        }
        sc.close(); //关闭扫描器
    }
}

 

3. 总结

 

判断字符的ASCII码大小的方法有以下几种:

  • 可以直接用比较运算符(如<, >, ==等)来比较两个字符的ASCII码大小,因为字符在计算机中是用ASCII码的二进制数来表示的,比较运算符会自动将字符转换为对应的数值进行比较。例如,‘a’ > 'A’的结果是true,因为’a’的ASCII码是97,'A’的ASCII码是65,97大于65。
  • 可以用强制类型转换(如(int)等)来将字符转换为整型数值,然后再比较它们的大小。例如,(int)‘a’ > (int)'A’的结果也是true,因为(int)'a’的值是97,(int)'A’的值是65。
  • 可以用isascii()函数来判断一个字符是否是ASCII码,即是否在0到127之间。如果是,返回非零值;如果不是,返回零。这个函数需要引入<ctype.h>头文件。例如,isascii(‘a’)的结果是非零值,isascii(‘中’)的结果是零。

你可以参考以下网址了解更多关于ASCII码和字符比较的知识:

posted on 2023-07-12 17:04  白露~  阅读(50)  评论(0编辑  收藏  举报