package com.***.util;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 字符串中连续的大写数字、小写数字作为一个整体进行比较
* 例如:负二,负1,一,二,一十一,22,211...
*/
public class StringComparator implements Comparator<String> {
/**
* @param str1
* @param str2
* @return a negative integer, zero, or a positive integer as the
* first argument is less than, equal to, or greater than the second.
*/
@Override
public int compare(String str1, String str2) {
int n1 = str1.length();
int n2 = str2.length();
for (int i1 = 0, i2 = 0; i1 < n1 && i2 < n2; ) {
NextItem item1 = getNextItem(str1, i1);
NextItem item2 = getNextItem(str2, i2);
boolean compared = false;
int flag = 0;
if (item1 != null && item2 != null) {
if (item1.isNum && item2.isNum) {
try {
flag = Integer.parseInt(item1.value) - Integer.parseInt(item2.value);
} catch (NumberFormatException e) {
e.printStackTrace();
flag = item1.value.compareTo(item2.value);
}
compared = true;
} else if (item1.isNum) {
return -1;
} else if (item2.isNum) {
return 1;
} else {
flag = item1.value.compareTo(item2.value);
compared = true;
}
} else if (item1 == null) {
return -1;
} else if (item2 == null) {
return 1;
}
if (compared) {
if (flag == 0) {
i1 = item1.nextIndex;
i2 = item2.nextIndex;
if (i1 >= n1 && i2 >= n2) {
return str1.compareTo(str2);
} else if (i1 >= n1) {
return -1;
} else if (i2 >= n2) {
return 1;
}
} else {
return flag;
}
}
}
return 0;
}
/**
* 查找连续字符的数字
*
* @param str
* @param index 开始查找位置
* @return
*/
private NextItem getNextItem(String str, int index) {
if (index >= str.length()) {
return null;
}
boolean isNum = false;
int nextIndex = index + 1;
String value = str.substring(index, nextIndex);
Pattern pattern = Pattern.compile("负?\\d+|负?[一二三四五六七八九][零一二三四五六七八九十百千万]*");
Matcher matcher = pattern.matcher(str);
if (matcher.find(index)) {
int start = matcher.start();
if (start == index) {
nextIndex = matcher.end();
value = str.substring(start, nextIndex);
value = getNumStr(value);
isNum = true;
}
}
return new NextItem(value, isNum, nextIndex);
}
private String getNumStr(String str) {
StringBuilder sb = new StringBuilder();
int n = str.length();
for (int i = 0; i < n; i++) {
String value = str.substring(i, i + 1);
if (NumMap.containsKey(value)) {
value = NumMap.get(value);
}
sb.append(value);
}
return sb.toString();
}
public static final Map<String, String> NumMap = new HashMap<String, String>() {
{
String str1 = "负零一二三四五六七八九十百千万";
String str2 = "-0123456789 ";
int n1 = str1.length();
for (int i = 0; i < n1; i++) {
this.put(str1.substring(i, i + 1), str2.substring(i, i + 1).trim());
}
}
};
private static class NextItem {
private String value; //值
private boolean isNum; //是否数字
private int nextIndex; //下一个开始位置
private NextItem(String value, boolean isNum, int nextIndex) {
this.value = value;
this.isNum = isNum;
this.nextIndex = nextIndex;
}
public String toString() {
return value + "," + isNum + "," + nextIndex;
}
}
}
字符串自然排序
最新推荐文章于 2025-03-17 17:58:34 发布