字符串字符类型排序问题-题目讲解

152 阅读3分钟

题目解析

小C需要对一个字符串进行特殊排序,字符串中包含字母、数字和问号。排序的规则如下:

  1. 问号:保持原始位置不变。
  2. 数字:保持原始位置不变,但需要按照从大到小的顺序进行排序。
  3. 字母:保持原始位置不变,但需要按照字典序从小到大的顺序进行排序。

思路

  1. 遍历字符串:首先遍历输入字符串,分别将数字和字母提取到两个不同的列表中。
  2. 排序:对数字列表进行降序排序,对字母列表进行升序排序。
  3. 重建字符串:再次遍历原始字符串,根据字符类型(数字、字母、问号)将排序后的字符放回原来的位置。

图解

  1. 假设输入字符串为 "1Ad?z?t24",处理过程如下:
  2. 提取数字:[1, 2, 4] → 排序后为 [4, 2, 1]
  3. 提取字母:[A, d, z] → 排序后为 [A, d, z]
  4. 重建字符串:
  • 原始位置:1 → 4
    
  • 原始位置:A → A
    
  • 原始位置:d → d
    
  • 原始位置:? → ?
    
  • 原始位置:z → z
    
  • 原始位置:? → ?
    
  • 原始位置:t → t
    
  • 原始位置:2 → 2
    
  • 原始位置:4 → 1
    

代码详解

1.定义主类

public static String solution(String inp) {

2.初始化结果存储,创建存储列表

  // 创建StringBuilder来存储结果
        StringBuilder result = new StringBuilder(inp);
        
        // 分别存储数字和字母
        List<Character> numbers = new ArrayList<>();
        List<Character> letters = new ArrayList<>();
        

3.遍历输入字符串

// 收集数字和字母
        for (char c : inp.toCharArray()) {
            if (Character.isDigit(c)) {
                numbers.add(c);
            } else if (Character.isLetter(c)) {
                letters.add(c);
            }
        }
  • Character.isDigit(c):检查字符是否为数字,如果是,则将其添加到numbers列表中。

  • Character.isLetter(c):检查字符是否为字母,如果是,则将其添加到letters列表中。

4.排序数字、字母;初始化索引

  // 对数字进行降序排序
        Collections.sort(numbers, Collections.reverseOrder());
        // 对字母进行升序排序
        Collections.sort(letters);
        
        // 分别记录数字和字母的索引
        int numIndex = 0;
        int letterIndex = 0;
        

5.重建字符串,返回

  // 重新填充字符串
        for (int i = 0; i < result.length(); i++) {
            char c = inp.charAt(i);
            if (Character.isDigit(c)) {
                result.setCharAt(i, numbers.get(numIndex++));
            } else if (Character.isLetter(c)) {
                result.setCharAt(i, letters.get(letterIndex++));
            }
            // 问号保持原位置不变
        }
        
        return result.toString();
  • inp.charAt(i):获取原始字符串中索引i处的字符。

  • 如果字符是数字,则用numbers列表中的下一个数字替换result中对应位置的字符,并增加numIndex。

  • 如果字符是字母,则用letters列表中的下一个字母替换result中对应位置的字符,并增加letterIndex。

个人思考与分析

这个问题的关键在于如何有效地提取和排序字符,同时保持原始位置。使用StringBuilder可以方便地修改字符串,而使用ArrayList来存储数字和字母则使得排序变得简单。通过两次遍历字符串,我们可以高效地完成任务。在实际应用中,这种字符处理的需求非常常见,尤其是在数据清洗和格式化时。理解并掌握这种处理方式,可以帮助我们在未来的编程中更好地应对类似问题。