【分享】Java中文字符串包含数字排序(自然语义)
前言:
根据需求,出现分类10,分类7,分类03类似的数据时,需要排程分类03,分类7,分类10,可参考如下实现。
原文鸣谢: https://www.cnblogs.com/interdrp/p/8970593.html
效果展示:
核心算法:
1.实现Comparetor,重写compare 原本是按照给定的排序规则,逐字符比较。需要改写成我们的规则
2.找到数字元素,进行比较。注意是同位置。
import java.util.Arrays;
import java.util.Comparator;
public class Demo {
public static void main(String[] args) {
String fileNames[] = {"分类1", "分类22", "分类081", "分类444", "分组", "分组1", "分类0070000000000000000000000000", "分组03", "我的祖国872", "分组009", "我的家乡99", "分组009开幕001", "分组009开幕12"};
char chFileNames[][] = new char[fileNames.length][];
String[] oldSortedNames = new String[fileNames.length];
for (int i = 0; i < fileNames.length; i++) {
chFileNames[i] = fileNames[i].toCharArray();
oldSortedNames[i] = fileNames[i];
}
Arrays.sort(chFileNames, ChsLogicCmp);
String line = null;
for (int i = 0; i < fileNames.length; i++) {
System.out.println(chFileNames[i]);
}
}
static Comparator<char[]> ChsLogicCmp = new Comparator<char[]>() {
class Int {
public int i;
}
public int findDigitEnd(char[] arrChar, Int at) {
int k = at.i;
char c = arrChar[k];
boolean bFirstZero = (c == '0');
while (k < arrChar.length) {
c = arrChar[k];
//first non-digit which is a high chance.
if (c > '9' || c < '0') {
break;
} else if (bFirstZero && c == '0') {
at.i++;
}
k++;
}
return k;
}
@Override
public int compare(char[] a, char[] b) {
if (a != null || b != null) {
Int aNonzeroIndex = new Int();
Int bNonzeroIndex = new Int();
int aIndex = 0, bIndex = 0,
aComparedUnitTailIndex, bComparedUnitTailIndex;
while (aIndex < a.length && bIndex < b.length) {
//aIndex <
aNonzeroIndex.i = aIndex;
bNonzeroIndex.i = bIndex;
aComparedUnitTailIndex = findDigitEnd(a, aNonzeroIndex);
bComparedUnitTailIndex = findDigitEnd(b, bNonzeroIndex);
//compare by number
if (aComparedUnitTailIndex > aIndex && bComparedUnitTailIndex > bIndex) {
int aDigitIndex = aNonzeroIndex.i;
int bDigitIndex = bNonzeroIndex.i;
int aDigit = aComparedUnitTailIndex - aDigitIndex;
int bDigit = bComparedUnitTailIndex - bDigitIndex;
//compare by digit
if (aDigit != bDigit)
return aDigit - bDigit;
//the number of their digit is same.
while (aDigitIndex < aComparedUnitTailIndex) {
if (a[aDigitIndex] != b[bDigitIndex])
return a[aDigitIndex] - b[bDigitIndex];
aDigitIndex++;
bDigitIndex++;
}
//if they are equal compared by number, compare the number of '0' when start with "0"
//ps note: paNonZero and pbNonZero can be added the above loop "while", but it is changed meanwhile.
//so, the following comparsion is ok.
aDigit = aNonzeroIndex.i - aIndex;
bDigit = bNonzeroIndex.i - bIndex;
if (aDigit != bDigit)
return aDigit - bDigit;
aIndex = aComparedUnitTailIndex;
bIndex = bComparedUnitTailIndex;
} else {
if (a[aIndex] != b[bIndex])
return a[aIndex] - b[bIndex];
aIndex++;
bIndex++;
}
}
}
return a.length - b.length;
}
};
}