字符串字符类型排序问题-青训营X豆包MarsCode 技术训练营刷题分享 | 豆包MarsCode AI 刷题

45 阅读7分钟

一、题目解析:特殊排序问题

问题描述

小C 需要对一个字符串进行特殊排序,这个字符串只包含三种字符类型:字母(大小写)、数字和问号。要求你按照以下规则进行排序:

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

输入

  • inp: 一个只包含字母、数字和问号的字符串

返回

  • 排序后的字符串

参数限制

  • 1 <= inp.length <= 1000

题目思路

  1. 分类字符:将字符串中的字符按类型(数字、字母、问号)分类存储。
  2. 排序字符:对数字按从大到小排序,对字母按字典序从小到大排序。
  3. 记录字符类型:使用枚举数组记录每个位置的字符类型。
  4. 重组字符串:根据原始位置和排序后的字符重组字符串。

具体操作步骤

  1. 分类字符

    • 遍历字符串,将字符按类型分类存储到不同的数组中。
  2. 记录字符类型

    • 使用枚举数组记录每个位置的字符类型。
  3. 排序字符

    • 对数字数组按从大到小排序。
    • 对字母数组按字典序从小到大排序。
  4. 重组字符串

    • 根据原始位置和排序后的字符重组字符串。

代码实现

public enum Type {
        DIGIT, LETTER, OTHER
    }

    public static Type classChar(char c) {
        if (Character.isDigit(c)) {
            return Type.DIGIT;
        } else if (Character.isLetter(c)&&c!='?') {
            return Type.LETTER;
        } else {
            return Type.OTHER;
        }
    }
    
public static String solution(String inp) {
        String[] arr= new String[3];
        arr[0]="";//数字
        arr[1]="";//字母
        arr[2]="";//问号
        Type[] types = new Type[inp.length()];
        //将字符串按类型分离
        for (int i = 0; i < inp.length(); i++) {
            char c=inp.charAt(i);
            Type typr=classChar(c);
            types[i]=typr;
            if (typr==Type.DIGIT) {
                arr[0]+=c;
            }
            if (typr==Type.LETTER) {
                arr[1]+=c;
            }
            if (typr==Type.OTHER) {
                arr[2]+=c;
            }
        }

        char[][] chars = new char[3][];
        chars[0]=arr[0].toCharArray();
        chars[1]=arr[1].toCharArray();
        chars[2]=arr[2].toCharArray();

        Arrays.sort(chars[0]);
        Arrays.sort(chars[1]);

        StringBuffer sb=new StringBuffer(new String(chars[0]));
        sb=sb.reverse();//数字反向

        String result ="";
        int i0=0,i1=0,i2=0;
        for(int i=0;i<inp.length();i++) {
            if(types[i]==Type.DIGIT) {
                result+=sb.charAt(i0);
                i0++;
            }
            else if(types[i]==Type.LETTER) {
                result+=chars[1][i1];
                i1++;
            }
            else{
                result+=chars[2][i2];
                i2++;
            }
        }
        return result;
    }

二、知识总结:

Java 中的字符串操作

Java 中的字符串是通过 String 类来表示的。以下是一些常用的字符串操作方法: 在 Java 中,字符串操作是通过 String 类来实现的。以下是一些常用的字符串操作方法:

  1. 创建字符串:可以通过直接赋值或使用 new 关键字来创建字符串。
  2. 字符串长度:使用 length() 方法可以获取字符串的长度。
  3. 字符串拼接:可以使用 + 运算符或 concat() 方法来拼接字符串。
  4. 字符串比较:可以使用 equals() 方法进行内容比较,使用 equalsIgnoreCase() 方法进行忽略大小写的比较,使用 compareTo() 方法进行字典序比较。
  5. 查找子字符串:可以使用 contains() 方法检查是否包含子字符串,使用 indexOf() 方法查找子字符串的位置,使用 lastIndexOf() 方法查找最后一次出现的位置,使用 startsWith() 和 endsWith() 方法检查前缀和后缀。
  6. 提取子字符串:可以使用 substring() 方法提取子字符串。
  7. 字符串替换:可以使用 replace() 方法替换字符或子字符串,使用 replaceAll() 方法根据正则表达式替换。
  8. 字符串拆分:可以使用 split() 方法根据正则表达式拆分字符串。
  9. 去除空白:可以使用 trim() 方法去除字符串两端的空白字符。
  10. 转换大小写:可以使用 toUpperCase() 方法将字符串转换为大写,使用 toLowerCase() 方法将字符串转换为小写。
  11. 字符串转字符数组:可以使用 toCharArray() 方法将字符串转换为字符数组

在实际开发中,字符串操作是非常常见的需求。掌握常用的字符串操作方法,可以大大提高开发效率和代码的可读性。以下是我的一些心得:

  1. 选择合适的方法:根据具体需求选择合适的字符串操作方法。例如,进行字符串拼接时,如果涉及大量拼接操作,建议使用 StringBuilder 或 StringBuffer 以提高性能。
  2. 注意字符串的不可变性:在 Java 中,字符串是不可变的,每次对字符串进行操作都会生成新的字符串对象。因此,在需要频繁修改字符串的场景下,使用 StringBuilder 或 StringBuffer 会更加高效。
  3. 正则表达式的应用:正则表达式在字符串查找、替换和拆分操作中非常强大。掌握正则表达式的基本语法,可以解决很多复杂的字符串处理问题。我之前的文章有一些正则表达式的一些基础介绍
  4. 处理特殊字符:在处理包含特殊字符的字符串时,需要特别注意转义字符的使用。例如,在正则表达式中,.*+ 等字符具有特殊含义,需要使用 \\ 进行转义。
  5. 性能优化:在处理大规模字符串数据时,需要注意性能问题。尽量避免在循环中频繁创建新的字符串对象,可以通过预分配内存或使用高效的字符串操作方法来优化性能。

Java 中的排序

在 Java 中,可以使用 Arrays.sort 方法对数组进行排序。对于基本数据类型的数组,使用默认的升序排序;对于对象数组,可以传入自定义的比较器来实现自定义排序。

// 对基本数据类型数组进行排序
int[] numbers = {35142};
Arrays.sort(numbers);

// 对对象数组进行排序
String[] strings = {"apple""orange""banana"};
Arrays.sort(strings);

// 自定义排序
Arrays.sort(strings, new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        return s2.compareTo(s1); // 降序排序
    }
});

枚举总结

什么是枚举

枚举(Enumeration)是一种特殊的类,用于表示一组固定的常量。枚举类型在许多编程语言中都有支持,包括 Java。使用枚举可以使代码更加清晰和易于维护,因为它提供了一种类型安全的方式来定义和使用常量。

枚举的特点

  1. 固定的常量集合:枚举类型定义了一组固定的常量,这些常量是枚举类型的唯一实例。
  2. 类型安全:枚举类型提供了类型安全的常量定义方式,避免了使用普通常量时可能出现的错误。
  3. 可读性和可维护性:使用枚举可以提高代码的可读性和可维护性,因为枚举常量有明确的名称和含义。

枚举的常见用法

  1. 定义枚举类型:枚举类型使用 enum 关键字定义,枚举常量用逗号分隔。
  2. 使用枚举常量:可以直接使用枚举类型的常量,枚举常量是枚举类型的静态成员。
  3. 枚举方法:枚举类型可以包含方法、字段和构造函数,可以像普通类一样使用。

枚举的优点

  1. 避免魔法值:使用枚举可以避免在代码中使用魔法值(magic numbers),使代码更加清晰。
  2. 类型检查:编译器会对枚举类型进行类型检查,避免了使用错误的常量值。
  3. 易于扩展:枚举类型可以很容易地添加新的常量,而不会影响现有代码。

枚举的应用场景

  1. 状态表示:枚举常用于表示一组有限的状态,例如订单状态(新建、处理中、已完成)。
  2. 选项和配置:枚举可以用于表示一组选项或配置,例如日志级别(DEBUG、INFO、WARN、ERROR)。
  3. 分类和类型:枚举可以用于表示一组分类或类型,例如文件类型(文本文件、图像文件、视频文件)。 如本文章解题使用枚举标记字符的种类