1. 题目第一个要求:英文字母从 A 到 Z 排列,不区分大小写。
    • 解决方案:可以使用桶排序
  2. 题目第二个要求:同一个英文字母的大小写同时存在时,按照输入顺序排列。
    • 解决方案:该要求相当于限制了一开始的桶排序不能随意记录个数,因此决定采用TreeMap,键为26个小写字母,值为了保存遍历的顺序,因此采用了StringBuilder对象。
    • 如果使用队列也是可以的,只是最后多一个取出的步骤。实测两种方式时间差不多,使用队列稍快
  3. 题目第三个要求:非英文字母的其它字符保持原来的位置。
    • 解决方案:按顺序遍历原始的字符串,获取到非字母的索引再插入到之前合并好的stringBuilder之中
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String original = "";
        while ((original = br.readLine()) != null) {

            // 遍历字符串并存入TreeMap中
            TreeMap<Character, StringBuilder> map = new TreeMap<>();
            for (char c: original.toCharArray()) {
                if ('a' <= c && c <= 'z') {
                    if (!map.containsKey(c)) {
                        map.put(c, new StringBuilder());
                    }
                    map.get(c).append(c);
                } else if ('A' <= c && c <= 'Z') {
                    char k = (char)(c - 'A' + 'a');
                    if (!map.containsKey(k)) {
                        map.put(k, new StringBuilder());
                    }
                    map.get(k).append(c);
                }
            }

            // 将已排序好的字母部分合并
            StringBuilder sb = new StringBuilder();
            for (Map.Entry<Character, StringBuilder> entry: map.entrySet()) {
                sb.append(entry.getValue());
            }

            // 重新遍历字符串以插入非字母的字符
            for (int i = 0; i < original.length(); i++) {
                char other = original.charAt(i);
                if ('a' <= other && other <= 'z') {
                    continue;
                } else if ('A' <= other && other <= 'Z') {
                    continue;
                } else {
                    sb.insert(i, other);
                }
            }
            System.out.println(sb.toString());
        }
        br.close();
    }
}