String类实现了Comparable接口,其compareTo方法中定义的是按该字符串的“字典顺序”比较大小,在这个字典中,采用通用的顺序,直接比各个单个的字符的大小,即数字比字母小。
而Collections.sort()方法正是基于Comparable接口的compareTo方法比较大小的。
所以你会得到这个结果。
如果要重定义顺序,在一般情况下,要重写compareTo方法,但是String类是final的,不能被继承修改,所以,你只好重新定义一个表示字符串的类了,很是麻烦。
这么做意味着你要自己实现各种需要用到的字符串方法。。。
重写compareTo之后,就可以使用各种排序器了。
这个方法该怎么写,自己抄String的compareTo的源代码吧,然后改一改。
主要就是加几条判断语句,让数字比字母大。
还有一种方案,自己重写一个排序器,在排序器中再定义两个String比较大小的方法。
排序的时候,使用自己的比较大小方法来比。比较方法还是如上所述,抄String的源码,然后修改字母比较大小的定义的路子。。
两种方案,自己根据需要选吧。
如果对String的其他操作不多,建议采用第一种。这样子自己不用写排序器。
看起来很简单的一个问题,实现起来比较麻烦的。
import java.util.ArrayList;
import java.util.List;
public class AllSort {
/**
* 从数组中选出所有组合
* @param source
* @param arrayList
* @param num
*/
public static void select(char[] source, ListString arrayList, int num) {
int lg = source.length;
char[] temp = new char[num];
System.arraycopy(source, 0, temp, 0, num);
// 首次填充数组
arrayList.add(new String(temp));
// 逐个(位置)替换方式实现不重复全选
for (int i = num; i lg; i++) {
for (int j = 0; j num; j++) {
char tempChar = temp[j];
temp[j] = source[i];
arrayList.add(new String(temp));
temp[j] = tempChar;
}
}
}
/**
* 全排序
* @param source
* @param start
* @param end
*/
public static void perm(char[] source, int start, int end) {
if (start == end) {// 递归出口,最简单的情况,只取出1个
for (int i = 0; i = end; i++) {
System.out.print(source[i]);
}
System.out.println();
} else {// 多个全排列
for (int i = start; i = end; i++) {
char temp = source;// 逐位交换
source = source[i];
source[i] = temp;
perm(source, start + 1, end);// 递归全排列
// 还原,为下个替换做准备
temp = source;
source = source[i];
source[i] = temp;
}
}
}
public static void main(String[] args) {
//char[] source = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'Aa-Zz...'};
char[] source = { '0', '1', '2', '3', '4','5','6','7','8','9' };
ArrayListString list = new ArrayListString();
for (int i = 1; i = source.length; i++) {
list.clear();
//选出
select(source, list, i);
System.out.println("===========取出"+i+"个==============");
//排列
for (String str : list) {
char[] temp = str.toCharArray();
perm(temp, 0, temp.length - 1);
}
}
}
}
之前在远标java时接触过!
import java.util.ArrayList;
import java.util.List;
public class Sort {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] nums = { "100A", "98.5", "98.5A", "34", "52", "100", "98",
"98.5B" };
// 冒泡排序法排序
for (int i = 0; i nums.length - 1; i++) {
for (int j = 0; j nums.length - i - 1; j++) {
double num1;// 前一个数字去字母后的数值
boolean char1 = false; // 前一个数字是否含有字母
int ascii1 = 0;// 前一个数字所含字母的ASCII码
// 获取每个数字的最后一位,判断是否为大写字母(判断其ASCII码是否在65到90之间)
if ((int) (nums[j].toCharArray()[nums[j].length() - 1]) = 65
(int) (nums[j].toCharArray()[nums[j].length() - 1]) = 90) {
num1 = Double.parseDouble(nums[j].substring(0,
nums[j].length() - 1));
char1 = true;
ascii1 = (int) (nums[j].toCharArray()[nums[j].length() - 1]);
} else {
num1 = Double.parseDouble(nums[j]);
}
double num2;// 后一个数字去字母后的数值
boolean char2 = false; // 后一个数字是否含有字母
int ascii2 = 0;// 后一个数字所含字母的ASCII码
// 获取每个数字的最后一位,判断是否为大写字母(判断其ASCII码是否在65到90之间)
if ((int) (nums[j + 1].toCharArray()[nums[j + 1].length() - 1]) = 65
(int) (nums[j + 1].toCharArray()[nums[j + 1]
.length() - 1]) = 90) {
num2 = Double.parseDouble(nums[j + 1].substring(0,
nums[j + 1].length() - 1));
char2 = true;
ascii2 = (int) (nums[j + 1].toCharArray()[nums[j + 1]
.length() - 1]);
} else {
num2 = Double.parseDouble(nums[j + 1]);
}
// 从大到小排序
if (num1 num2) {
String temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
} else if (num1 == num2) {// 数值相等则判断是否有字母以及字母的顺序
// 如果两个都有字母,则判断顺序
if (char1 char2) {
// 按ASCII码从小到大排列(即从A到Z排列)
if (ascii1 ascii2) {
String temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
} else if (!char1 char2) {// 如果后面一个数字有字母
String temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
}
}
for (int i = 0; i nums.length; i++) {
System.out.println(nums[i]);
}
}
}
我为了赋值方便,用的是String数组,但是跟用list没有区别,方法还是一样的,只是获取长度的时候调的方法不同。数组用.length, list用的是.size()。
简单帮你实现了下,有问题再追问。
public static String sortArray(String str) {
StringBuffer letterBuffer = new StringBuffer();
StringBuffer numberBuffer = new StringBuffer();
for(char c : str.toCharArray()) {
if(c = '0' c = '9')
numberBuffer.append(c);
else
letterBuffer.append(c);
}
return letterBuffer.toString() + numberBuffer.toString();
}
public static void main(String[] args) {
// test
String test = "1a2b3c4d";
System.out.println(sortArray(test));
}
你是想自己写排序算法呢还是直接用Java提供的API呢?如果想用JAVA里面的API那就推荐你用Arrays里面的sort方法,你可以为这种A--13,D--6,S--9,F--15,T--13创建一个实现Comparable接口的对象,实现里面的compareTo方法来定义你的字母所对应的大小。前者你就好好想想用什么算法实现吧,后者我写了一个实例:
import java.util.Arrays;
public class TestCompare implements ComparableTestCompare {
private final char c;
private final int i;
/**
* @return the string
*/
public char getC() {
return c;
}
/**
* @return the i
*/
public int getI() {
return i;
}
public TestCompare(char c, int i) {
this.i = i;
this.c = c;
}
public int compareTo(TestCompare o) {
// TODO Auto-generated method stub
if (o == null) {
// 表示当前实例的位置在o之后
return 1;
} else {
// 先比较数字
if (this.getI() o.getI()) {
// 表示当前实例的位置在o之前
return -1;
} else if (this.getI() == o.getI()) {
// 数字相等开始比较字母
// char型强转成int行,A到Z各代表多少值应该都知道吧
if (this.getC() o.getI()) {
// 表示当前实例的位置在o之前
return -1;
} else if (this.getC() == o.getI()) {
// 表示当前实例的位置在o相等
return 0;
} else {
// 表示当前实例的位置在o之后
return 1;
}
} else {
// 表示当前实例的位置在o之后
return 1;
}
}
}
@Override
public String toString() {
return new Character(this.getC()).toString();
};
public static void main(String[] args) {
TestCompare[] compare = new TestCompare[] { new TestCompare('A', 13),
new TestCompare('D', 6), new TestCompare('S', 9),
new TestCompare('F', 15), new TestCompare('T', 13) };
Arrays.sort(compare);
for (TestCompare compare2 : compare) {
System.out.print(compare2);
}
}
}
简单说一下关键点:
char c = 'A'; // 大写字母A
int cInt = Character.digit(c, 10); // 获取A的编码,应为65,10为基数
cInt = cInt + 7; // 字符后移
c = Character.forDigit(cInt, 10); // 通过编码获取字符,10为基数
这样就可以了,至于掉转,方法就多了。最简单的,你在每个加7的时候,其实第1个加了10,第2个加了9,第3个加8,第4个加7。这样自来就换了位置。