首页 > 编程语言 >Java字符串按字符排序的方法

Java字符串按字符排序的方法

时间:2023-07-14 22:23:02浏览次数:29  
标签:Java String int 字符串 new strList 排序

 

Java字符串按字符排序的方法

字符串排序是一种常见的编程需求,它可以让我们按照一定的规则对字符串进行比较和排列。在Java中,有多种方法可以实现字符串按字符排序,本文将介绍四种常用的方法,并给出相应的示例代码。

1. 使用String类的compareTo()方法

String类提供了一个compareTo()方法,它可以按照字典顺序比较两个字符串。如果两个字符串相等,返回0;如果第一个字符串在字典顺序上小于第二个字符串,返回一个负数;如果第一个字符串在字典顺序上大于第二个字符串,返回一个正数。利用这个方法,我们可以对一个字符串数组或集合进行排序,例如:

//使用Arrays.sort()对字符串数组排序
String[] strArr = new String[]{"zhangsan","lisi","wangwu"};
Arrays.sort(strArr);
System.out.println("默认按字母升序排序:");
for (String str:strArr) {
    System.out.println(str);
}

//使用Collections.sort()对字符串集合排序
List<String> strList = new ArrayList<>();
strList.add("zhangsan");
strList.add("lisi");
strList.add("wangwu");
Collections.sort(strList);
System.out.println("默认按字母升序排序:");
for (String str:strList) {
    System.out.println(str);
}

输出结果为:

默认按字母升序排序:
lisi
wangwu
zhangsan
默认按字母升序排序:
lisi
wangwu
zhangsan

2. 使用Comparator接口自定义排序规则

如果我们想要按照自定义的规则对字符串进行排序,例如按照字符串的长度或者逆序等,我们可以使用Comparator接口来实现。Comparator接口是一个函数式接口,它有一个抽象方法compare(T o1, T o2),用来比较两个对象。我们可以通过lambda表达式或者匿名内部类来创建Comparator对象,并传递给Arrays.sort()或者Collections.sort()方法。例如:

//使用lambda表达式创建Comparator对象
Comparator<String> cmp = (s1, s2) -> s1.length() - s2.length(); //按照字符串长度升序排序

//使用匿名内部类创建Comparator对象
Comparator<String> cmp = new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        return s1.length() - s2.length(); //按照字符串长度升序排序
    }
};

//使用Arrays.sort()对字符串数组排序
String[] strArr = new String[]{"zhangsan","lisi","wangwu"};
Arrays.sort(strArr, cmp); //传入自定义的Comparator对象
System.out.println("自定义排序,按字符串长度升序排序:");
for (String str:strArr) {
    System.out.println(str);
}

//使用Collections.sort()对字符串集合排序
List<String> strList = new ArrayList<>();
strList.add("zhangsan");
strList.add("lisi");
strList.add("wangwu");
Collections.sort(strList, cmp); //传入自定义的Comparator对象
System.out.println("自定义排序,按字符串长度升序排序:");
for (String str:strList) {
    System.out.println(str);
}

输出结果为:

自定义排序,按字符串长度升序排序:
lisi
wangwu
zhangsan
自定义排序,按字符串长度升序排序:
lisi
wangwu
zhangsan

3. 使用键索引计数法

键索引计数法是一种适用于小整数键的简单排序方法。它通过统计每个键出现的频率,然后将频率转换为索引,再将元素分类和回写。这种方法本身就很实用,同时也是后面要介绍的两种基于字符的排序方法的基础。

假设我们有一个学生类Student,它有两个属性:name和key。key是一个0到R-1之间的整数,表示学生所属的组别。我们想要按照key的顺序对学生进行排序,可以使用以下代码:

class Student {
    String name;
    int key; //组号
    public Student(String name, int key) {
        this.name = name;
        this.key = key;
    }
    public int key() {
        return key;
    }
}

public class KeyIndexSort {
    public static void sort(Student[] s, int R) {
        int N = s.length;
        int[] count = new int[R + 1];
        Student[] aux = new Student[N];
        //第一步:频率统计
        for (int i = 0; i < N; i++) {
            count[s[i].key() + 1]++;
        }
        //第二步:频率转换为索引
        for (int r = 0; r < R; r++) {
            count[r + 1] += count[r];
        }
        //第三步:数据分类排序
        for (int i = 0; i < N; i++) {
            aux[count[s[i].key()]++] = s[i];
        }
        //第四步:回写排序好的数组
        for (int i = 0; i < N; i++) {
            s[i] = aux[i];
        }
    }

    public static void main(String[] args) {
        Student[] students = new Student[10];
        students[0] = new Student("zhangsan", 2);
        students[1] = new Student("lisi", 1);
        students[2] = new Student("wangwu", 3);
        students[3] = new Student("zhaoliu", 2);
        students[4] = new Student("qianqi", 4);
        students[5] = new Student("sunba", 1);
        students[6] = new Student("zhoujiu", 3);
        students[7] = new Student("wushi", 4);
        students[8] = new Student("liushi", 2);
        students[9] = new Student("qishi", 1);
        
        sort(students, 5); //假设有5个组别
        
        System.out.println("按照组号升序排序:");
        
        for (Student student:students) {
            System.out.println(student.name + " " + student.key);
        }
    }
}

输出结果为:

按照组号升序排序:
lisi 1
sunba 1
qishi 1
zhangsan 2
zhaoliu 2
liushi 2
wangwu 3
zhoujiu 3
qianqi 4
wushi 4

4. 使用低位优先的字符串排序

低位优先的字符串排序是一种适用于定长字符串的排序方法,它从右到左以每个位置的字符作为键,用键索引计数法将字符串排序 W 遍,其中 W 是字符串的长度。这种方法可以保证相同位置的字符相等的字符串在排序后仍然保持相对顺序。

假设我们有一个定长为3的字符串数组,我们想要按照字典顺序对它进行排序,可以使用以下代码:

public class LSDSort {
    public static void sort(String[] a, int W) {
        //通过前W个字符将a[]排序
        int N = a.length;
        int R = 256; //基数,假设是扩展ASCII码
        String[] aux = new String[N]; //辅助数组
        
        for (int d = W - 1; d >= 0; d--) {
            //根据第d个字符用键索引计数法排序
            
            int[] count = new int[R + 1]; //计算出现频率
            
            for (int i = 0; i < N; i++) {
                count[a[i].charAt(d) + 1]++;
            }
            
            for (int r = 0; r < R; r++) {
                //将频率转换为索引
                count[r + 1] += count[r];
            }
            
        for (int i = 0; i < N; i++) {
                //将元素分类
                aux[count[a[i].charAt(d)]++] = a[i];

   for (int i = 0; i < N; i++) {
                //回写
                a[i] = aux[i];
            }
        }
    }

    public static void main(String[] args) {
        String[] strArr = new String[]{"abc","def","ghi","jkl","mno","pqr","stu","vwx","yz"};
        sort(strArr, 3); //假设字符串长度为3
        
        System.out.println("按照字典顺序排序:");
        
        for (String str:strArr) {
            System.out.println(str);
        }
    }
}

输出结果为:

按照字典顺序排序:
abc
def
ghi
jkl
mno
pqr
stu
vwx
yz

这就是低位优先的字符串排序的方法,它可以快速地对定长字符串进行排序,但是对于变长字符串或者不同长度的字符串,它就不适用了。下面我们来看另一种基于字符的排序方法,它可以处理变长字符串的情况。

5. 使用高位优先的字符串排序

高位优先的字符串排序是一种适用于变长字符串的排序方法,它从左到右以每个位置的字符作为键,用键索引计数法将字符串按首字母排序,然后递归地对每个首字母对应的子数组排序。这种方法和快速排序类似,都是通过切分和递归来完成排序任务,但是它的切分会为每个首字母得到一个子数组,而不是像快速排序中那样产生固定的两个或者三个切分。

假设我们有一个变长的字符串数组,我们想要按照字典顺序对它进行排序,可以使用以下代码:

public class MSDSort {
    //高位优先的字符串排序
    
    private static int R = 256; //基数,假设是扩展ASCII码
    private static final int M = 15; //小数组的切换阈值
    private static String[] aux; //数组分类的辅助数组
    
    private static int charAt(String s, int d) {
        //返回字符串s中第d个字符的索引,如果d超过了s的长度,返回-1
        if (d < s.length()) {
            return s.charAt(d);
        } else {
            return -1;
        }
    }
    
    public static void sort(String[] a) {
        //对字符串数组a进行排序
        int N = a.length;
        aux = new String[N];
        sort(a, 0, N - 1, 0); //从第0个字符开始排序
    }
    
    private static void sortInsert(String[] a, int lo, int hi) {
        //对小型数组进行插入排序
        for (int i = lo + 1; i <= hi; i++) {
            for (int j = i; j > lo && a[j].compareTo(a[j - 1]) < 0; j--) {
                String tmp = a[j];
                a[j] = a[j - 1];
                a[j - 1] = tmp;
            }
        }
    }
    
    private static void sort(String[] a, int lo, int hi, int d) {
        //以第d个字符为键将a[lo]至a[hi]排序
        
        if (hi <= lo + M) {
            //如果子数组较小,使用插入排序提高效率
            sortInsert(a, lo, hi);
            return;
        }
        
        int[] count = new int[R + 2]; //计算频率
        
        for (int i = lo; i <= hi; i++) {
            count[charAt(a[i], d) + 2]++;
        }
        
        for (int r = 0; r < R + 1; r++) {
            //将频率转换为索引
            count[r + 1] += count[r];
 

标签:Java,String,int,字符串,new,strList,排序
From: https://www.cnblogs.com/shoshana-kong/p/17555133.html

相关文章

  • Java Comparator接口的介绍与使用
    JavaComparator接口的介绍与使用什么是Comparator接口?Comparator接口是一个用于比较两个对象大小的接口,它定义了一个抽象方法compare(To1,To2),根据o1和o2的大小返回一个整数值。Comparator接口位于java.util包中,它是一个泛型接口,可以指定比较的对象类型。Comparator接口的......
  • Java swing和JavaFX学习笔记
    JAVAFX与JAVASwing的区别与推荐:学习Java界面编程是选择Swing还是JavaFX?_javafxswing_莱迪娜的歌声的博客-CSDN博客swing中一些基础函数介绍:JButton按钮,按钮可以带一些图片或文字JCheckBox复选框JComBox下拉列表框,可以在下拉显示区域显示多个选项JFrame框架类......
  • 大一下java期末设计:学生信息管理系统(荣获班上第一)
    先上java代码:先上java代码:importjava.awt.*;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.sql.*;importjava.util.Scanner;importjavax.swing.*;publicclasscs2extendsJFrame{publicstaticvoidmain(String[]args......
  • HJ26 字符串排序
    1.题目读题HJ26 字符串排序   考查点 2.解法思路 代码逻辑 具体实现 publicclassHJ026{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);System.out.println(sort(sc.nextLine()));}publ......
  • 学科知识图谱学习平台项目 :技术栈Java、Neo4j、MySQL等超详细教学
    学科知识图谱学习平台项目:技术栈Java、Neo4j、MySQL等超详细教学0.效果展示1.安装教程安装JavaSDK11,下载前需要登录Oracle账号,下载链接,安装教程,测试是否能在命令行工具调用javajava--versionjava17.0.12021-10-19LTSJava(TM)SERuntimeEnvironment(build......
  • java8 LocalData/Time
    ISO_DATE_TIMELStringtimeString=LocalDateTime.now().atOffset(ZoneOffset.ofHours(8)).format(DateTimeFormatter.ISO_DATE_TIME);System.out.println(timeString);//2023-07-14T18:28:23.056+08:00增加与减小LocalDatedate=LocalDate.now().minusMonths(1);LocalDa......
  • Java POM Dependency
     <projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">......
  • java拦截器获取POST请求体后Controller异常Required request body is missing OR Stre
    解决办法参考文档:https://blog.csdn.net/qierkang/article/details/88544691springboot拦截器获取POST请求体后导致Controller中@RequestBody参数异常RequiredrequestbodyismissingORStreamclosed.1.为什么会报这个错?因为http的body只能读取一次。2.为什么body设计为只......
  • Java入门13(socket)
    Socket编程(网络通信)服务器端Demo(ServreSocket)​ 创建服务端时,如果不提供IP地址,则默认为本地连接(127.0.0.1),但是一定需要手动配置监听端口!publicstaticvoidmain(String[]args){//如果不提供IP地址,默认localhost//但是服务器端的端口号需要手动指令try(Serv......
  • java--String类的常用方法
    一、获取1、length()  获取字符串长度Stringstr="ahcckmvevawe";System.out.println(str.length());//输出122、charAt(intindex)  返回下标对应的字符Stringstr="ahcckmvevawe";System.out.println(str.charAt(4));//输出k3、indexOf()  返回字符对......