Java中利用compareTo方法进行字符串比较排序

**

利用compareTo方法进行字符串比较排序

**

排序算法

创建学生类,包含两个属性:姓名和学号。给出构造函数,输入参数为学生学号,限制为整型类型,范围在[0,999]之间。姓名由3位字符组成,由该学生的学号采用线性映射的方式获取得到,线性映射函数为(见表1)
在这里插入图片描述
要求输入一个范围在[0,999]之间的整数,通过随机产生的方式生成n个满足上述要求的学生对象。并按照以下三种不同的排序方式完成所有对象的顺序输出:
(a) 按照学号的大小顺序完成顺序输出,即给出两个学生s和t,对应学号分别为:m和n,若满足m>n,则要求先输出t后输出s;
(b) 按照学生对应学号的十位、个位、百位的大小优先顺序完成顺序输出,即
给出两个学生s和t,对应学号分别为:m和n,若m的十位数大于n的十位数,则先输出m,若两者相等,再比较m和n的个位数,相应小的对象先输出;若两位学生的十位、个位均相等,最后比较两个学号的百位数,相应小的先输出。如两个学生的学号分别为:045和418,由于第二个学生的学号十位数1小于第一个学生的十位数4,需要先输出第二个学生对象;
(c ) 按照学生对应学号的个位、百位、十位的大小优先顺序完成顺序输出,即给出两个学生s和t,对应学号分别为:m和n,若m的个位数大于n的个位数,则先输出m,若两者相等,再比较m和n的百位数,相应小的对象先输出;若两位学生的个位、百位均相等,最后比较两个学号的十位数,相应小的先输出。如两个学生的学号分别为:248和418,由于两位学生的个位数相等,需要再比较两个学号的百位数,而需要先输出第一个学生对象。

程序源代码如下:

package sunhao;

import java.util.Scanner;


abstract class CompareTo{	//定义一个抽象类和抽象方法
	abstract public void compare(String [] str);	//该方法用于比较字符串的大小
}
class Compare extends CompareTo{	//继承上面抽象类并重写父类的abstract方法
	public void compare(String [] m){	//三位数学号的字符串作为参数传入
		for(int i=0;i<m.length;i++) {
			for(int j=0;j<i;j++) {
				String str=String.valueOf(m[i]);
				String str1=String.valueOf(m[j]);
				int w=str.compareTo(str1);	//等长字符串比较
				if(w<0) {	//按从小到大排序
					String temp=m[i];
					m[i]=m[j];
					m[j]=temp;
				}
			}
		}
		
	}
}
class Compare1 extends CompareTo{	//按十个百位进行比较
	public void compare(String [] m){
		String [] n=new String[m.length];
		for(int r=0;r<m.length;r++) {
			int sno=Integer.parseInt(m[r]);
			int a=sno/100;
			int b=(sno%100)/10;
			int c=sno%10;
			int snoo=b*100+c*10+a;	//将原来的学号变成十个百位顺序
			n[r]=String.format("%03d", snoo);
		}
		for(int i=0;i<m.length;i++) {
			for(int j=0;j<i;j++) {
				String str=String.valueOf(n[i]);
				String str1=String.valueOf(n[j]);
				int w=str.compareTo(str1);
				if(w<0) {
					String temp=n[i];
					n[i]=n[j];
					n[j]=temp;
				}
			}
		}
		for(int t=0;t<m.length;t++) {
			int sno=Integer.parseInt(n[t]);
			int a=sno/100;
			int b=(sno%100)/10;
			int c=sno%10;
			int snoo=c*100+a*10+b;	//比较完再将学号恢复
			m[t]=String.format("%03d", snoo);
		}
	}
}
class Compare2 extends CompareTo{	按个百十位进行比较
	public void compare(String [] m){
		String [] n=new String[m.length];
		for(int r=0;r<m.length;r++) {
			int sno=Integer.parseInt(m[r]);
			int a=sno/100;
			int b=(sno%100)/10;
			int c=sno%10;
			int snoo=c*100+a*10+b;
			n[r]=String.format("%03d", snoo);
		}
		for(int i=0;i<m.length;i++) {
			for(int j=0;j<i;j++) {
				String str=String.valueOf(n[i]);
				String str1=String.valueOf(n[j]);
				int w=str.compareTo(str1);
				if(w<0) {
					String temp=n[i];
					n[i]=n[j];
					n[j]=temp;
				}
			}
		}
		for(int t=0;t<m.length;t++) {
			m[t]=n[t];
			int sno=Integer.parseInt(m[t]);
			int a=sno/100;
			int b=(sno%100)/10;
			int c=sno%10;
			int snoo=b*100+c*10+a;
			m[t]=String.format("%03d", snoo);
		}
	}
}
class Repeat{	//随机生成不重复的学号
	public void repeat(int [] sno){
		int i=0;
		while(true) {	//去除重复学号
			boolean flag=true;
			int no=(int)(Math.random()*1000);	//随机生成0-999之间的数
			for(int j=0;j<sno.length;j++) {
				if(sno[j]==no) {
					flag=false;
					break;
				}
			}
			if(flag) {
				sno[i]=no;
				i++;
			}
			if(i>sno.length-1) {
				break;
			}
		}
	}
}
class Student{	//定义一个学生类
	String sname;	//学生的姓名
	int sno;	//学生的学号
	Student(String ssno){	//构造函数
		int sno=Integer.parseInt(ssno);
		String [] t= {"A","B","C","D","E","F","G","H","I","J"};	//定义一个字符串数组
		int a=sno/100;	//将三位数学号拆开(a代表百位)
		int b=(sno%100)/10;	//b代表十位
		int c=sno%10;	//c代表个位
		System.out.println("     "+t[a]+t[b]+t[c]);	//根据学生学号与姓名的映射关系,输出该学号对应的学生姓名
	}
}
public class Test{	//主类
	public static void main(String args[]) {
		Scanner sc=new Scanner(System.in);	//Scanner类用于用户的输入
		System.out.println("请输入学生个数:");
		try{	//try用于捕获用户输入时的异常(如非数字),并来提示用户重新输入
			int number=sc.nextInt();	//输入学生的个数
			if(number>=0&&number<=999) {	//学生的个数应为0-999之间
				int [] sno=new int[number];	//为这些学生创建一个学号数组,存放学号(学号唯一)
				Repeat re=new Repeat();	//对象的声明与实例化
				re.repeat(sno);	//调用Repeat类中的repeat方法
				String [] ssno=new String[number];	//存放三位数学号
				System.out.println("----------------------------------------------------------");
				System.out.println("(a)按照学号的大小顺序完成顺序输出:");
				System.out.println("序号    "+"学号     "+"姓名");
				for(int k=0;k<sno.length;k++) {	//将随机生成的学号全部变成三位数的字符串
					ssno[k]=String.format("%03d", sno[k]);//0表示前面补0;digit表示要保留的数字位数;d表示参数为正数类型
				}
				Compare com=new Compare();
				com.compare(ssno);	//按顺序比较
				for(int r=0;r<sno.length;r++) {	//输出结果
					System.out.print(r+1);	//序号
					System.out.print("    "+ssno[r]);	//学号
					Student stu=new Student(ssno[r]);	//姓名
				}
				System.out.println("----------------------------------------------------------");
				System.out.println("(b)按照学生对应学号的十位、个位、百位的大小优先顺序完成顺序输出:");
				System.out.println("序号    "+"学号     "+"姓名");
				for(int k=0;k<sno.length;k++) {
					ssno[k]=String.format("%03d", sno[k]);
				}
				Compare1 com1=new Compare1();
				com1.compare(ssno);
				for(int r=0;r<sno.length;r++) {
					System.out.print(r+1);
					System.out.print("    "+ssno[r]);
					Student stu1=new Student(ssno[r]);
				}
				System.out.println("----------------------------------------------------------");
				System.out.println("(c)按照学生对应学号的个位、百位、十位的大小优先顺序完成顺序输出:");
				System.out.println("序号    "+"学号     "+"姓名");
				for(int k=0;k<sno.length;k++) {
					ssno[k]=String.format("%03d", sno[k]);
				}
				Compare2 com2=new Compare2();
				com2.compare(ssno);
				for(int r=0;r<sno.length;r++) {
					System.out.print(r+1);
					System.out.print("    "+ssno[r]);
					Student stu2=new Student(ssno[r]);
				}
			}else {	//当输入不在0-999之间进行提醒
				System.out.println("请输入0-999之间的数字!(包括0和999)");
			}
		}catch(Exception e) {	//捕获异常并提醒
			System.out.println("亲,您输入的不是数字。请输入0-999之间的数字!(包括0和999)");
		}
	}
}

运行结果:

请输入学生个数:
6
----------------------------------------------------------
(a)按照学号的大小顺序完成顺序输出:
序号    学号     姓名
1    117     BBH
2    140     BEA
3    222     CCC
4    726     HCG
5    777     HHH
6    807     IAH
----------------------------------------------------------
(b)按照学生对应学号的十位、个位、百位的大小优先顺序完成顺序输出:
序号    学号     姓名
1    807     IAH
2    117     BBH
3    222     CCC
4    726     HCG
5    140     BEA
6    777     HHH
----------------------------------------------------------
(c)按照学生对应学号的个位、百位、十位的大小优先顺序完成顺序输出:
序号    学号     姓名
1    140     BEA
2    222     CCC
3    726     HCG
4    117     BBH
5    777     HHH
6    807     IAH

小结:
(1)Math.random()方法的使用:
Math.random()会随机生成[0,1)之间的随机数,一般情况下会在Math.Random()上乘以一个数,如乘以n。这样我们就可以生成[0,n)之间的随机数。如果用int进行取整的话,那么我们就可以产生[0,n)之间的正整数。包含0,不包含n。
(2)Java中的compareTo方法,返回比较前后的两个字符串的ASCII的差值。

a.等长字符串比较:参与比较的两个字符串如果首字符相同,则比较下一个字符,直到有不同的为止,返回该不同的字符的ASCII差值。
a = “abc”;
b = “bac”;
a.compareTo(b)//-1

a = “abc”;
b = “acb”;
a.compareTo(b)//-1

b.不等长字符串比较:
两个字符串首字母不同,则该方法返回首字母的ASCII的差值
a = “abc”;
b = “bcdfg”;
a.compareTo(b)//-1

参与比较的两个字符串如果首字符相同,则比较下一个字符,直到有不同的为止,返回该不同的字符的ASCII差值
a = “abc”;
b = “abedfg”;
a.compareTo(b)//-2

两个字符串不一样长,可以参与比较的字符又完全一样,则返回两个字符串的长度差值
a = “abcde”;
b = “abcd”;
a.compareTo(b)//1

你可能感兴趣的:(笔记,java,字符串,算法)