字符串排序
1.题目描述
请对组字符串进行排序,字符串由大小写字母和数字组成,需要满足以下比较规则
- 1、长度不同时,长度较短在排前面
- 2、长度相同时,按照字典顺序排列(AaBb-Zz, 0-9顺序),即大写字母在小写字母前,数字排在字母后,要求时间复杂度为O(nlogn)。
比如:
abc Abc 123 1bc CBD abed a
排序后结果为:
a 1 Abc abc CBD 1bc 123 abcd
2.解题思路
ASCII码:0-9(对应数值48-59);A-Z(对应数值65-90);a-z(对应数值97-122);
排序为(AaBb-Zz, 0-9顺序),不符合常规字典排序,故这里我重新定义了ASCII码,因为A和a的ascii码相差32,这里定义A的ascii码为32,依次排序为
字符 | 重新定义的ASCII码 | 字符 | 重新定义的ASCII码 | 字符 | 重新定义的ASCII码 |
---|---|---|---|---|---|
A | 32 | L | 54 | v | 75 |
a | 33 | l | 55 | W | 76 |
B | 34 | M | 56 | w | 77 |
b | 35 | m | 57 | X | 78 |
C | 36 | N | 58 | x | 79 |
c | 37 | n | 59 | Y | 80 |
D | 38 | O | 60 | y | 81 |
d | 39 | o | 61 | Z | 82 |
E | 40 | P | 62 | z | 83 |
e | 41 | p | 63 | 0 | 84 |
F | 42 | Q | 64 | 1 | 85 |
f | 43 | q | 65 | 2 | 86 |
G | 44 | R | 66 | 3 | 87 |
g | 45 | r | 67 | 4 | 88 |
H | 46 | S | 68 | 5 | 89 |
h | 47 | s | 69 | 6 | 90 |
I | 48 | T | 70 | 7 | 91 |
i | 49 | t | 71 | 8 | 92 |
J | 50 | U | 72 | 9 | 93 |
j | 51 | u | 73 | ||
K | 52 | V | 74 | ||
k | 53 |
故可以根据原来的ascii推出现在定义的ASCII码:
- (1) 假设字符为 A-Z,则有 ascii = (str1.charAt(i) - ‘A’) * 2 + 32;
- (2) 假设字符为 a-z,则有 ascii = (str1.charAt(i) - ‘a’) * 2 + 33;
- (3) 假设字符为 0-9,则有 ascii = str1.charAt(i) + 36;
(1) 用TreeSet存储字符串,因为TreeMap会自动给其排序
(2) 重写Compare方法,将其长度按照从小到大排序
3.代码
import java.util.*;
public class Main_1 {
public static void main(String[] args) {
String[]arr = {
"abc","Abc","123","1","1bc","CBD","abcd","a"};
Set strSet = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
String str1 = (String) o1;
String str2 = (String) o2;
int temp = str1.length()-str2.length();
//如果两个数组的长度相等则直接按字典序排列,但是这个字典序不是常规的[0-9 A-Z a-z ]
//而是[AaBb-Zz 0-9]类型,故不能直接用str1.compareTo(str2)方法,要重新计算他的ascii码
//如果两个数组的长度相等则直接按字典序排列
if(temp==0){
int t1=0;
int t2=0;
for(int i=0;i<s