使用java比较器对字符数组进行排序
Posted
技术标签:
【中文标题】使用java比较器对字符数组进行排序【英文标题】:Sort character array using java comparator 【发布时间】:2022-01-20 07:26:38 【问题描述】:按字典顺序对字符数组进行排序,附加条件是所有 c 都在所有 b 之前。这可以手动完成,但我想使用比较器通过内置排序对其进行编码。我写的代码-
static class Sort implements Comparator<Character>
@Override
public int compare(Character x, Character y)
if(x == 'c' && y == 'b')
return y - x;
return x - y;
public static void main(String[] args)
String s = "abracadabra";
int n = s.length();
Character[] res = new Character[n];
for (int i = 0; i < n; i++)
res[i] = s.charAt(i);
Arrays.sort(res, new Sort());
System.out.println(Arrays.toString(res));
给出输出:[a, a, a, a, a, b, c, b, d, r, r]。 c 只出现在 b 之一之前。如果我将比较器更改为以下,那么它会给出正确的输出。
public int compare(Character x, Character y)
if(x == 'c' && y == 'b' || x == 'b' && y == 'c')
return y - x;
return x - y;
我的问题是为什么在这两种情况下返回“y-x”都会给出正确答案?如果在一种情况下返回“y-x”是正确的,那么在另一种情况下不应该返回“x-y”是正确的吗?而不是“y-x”,返回 -1 或 +1 也不起作用。 PL。解释内部发生的事情。谢谢!
【问题讨论】:
如果你反转参数,你必须否定结果。 【参考方案1】:问题在于,如果传递 'c'
和 'b'
使比较返回负值,那么传递 'b'
和 'c'
应该返回正值(在这种情况下,您的第一个版本返回负数反而)。如果无论参数的顺序如何,函数都没有返回一致的结果,那么排序算法就会产生垃圾顺序。
考虑这个版本:
public int compare(Character x, Character y)
if (x == 'c' && y == 'b')
return -1;
else if (x == 'b' && y == 'c')
return 1;
else
return x.compareTo(y);
【讨论】:
(我不太喜欢使用减法来比较两个值;在这样做的 C 程序中曾多次遇到溢出问题)【参考方案2】:您可以添加System.out.println()
以了解其工作原理:
代码
import java.util.Arrays;
import java.util.Comparator;
public class Main
public static void main(String[] args)
String s = "abracadabra";
int n = s.length();
System.out.println("X Y\tX Y\t[if] VALUE");
System.out.println();
Character[] res = new Character[n];
for (int i = 0; i < n; i++)
res[i] = s.charAt(i);
int min = 'a';
Arrays.sort(res, new Comparator<Character>()
@Override
public int compare(Character x, Character y)
System.out.print(y + " " + x + "\t" + (x-min) + " " + (y-min) + "\t");
if(x == 'c' && y == 'b')
System.out.println("true " + (y - x));
return y - x;
System.out.println(" " + (x - y));
return x - y;
);
System.out.println("#################################\nResult:\n" + Arrays.toString(res));
控制台:
X Y X Y [if] VALUE
a b 1 0 1
b r 17 1 16
r a 0 17 -17
b a 0 1 -1
a a 0 0 0
b c 2 1 true -1
a c 2 0 2
c a 0 2 -2
a a 0 0 0
c d 3 2 1
r d 3 17 -14
b d 3 1 2
c a 0 2 -2
a a 0 0 0
a a 0 0 0
c b 1 2 -1
a b 1 0 1
a b 1 0 1
b r 17 1 16
d r 17 3 14
r r 17 17 0
c a 0 2 -2
a a 0 0 0
b a 0 1 -1
a a 0 0 0
#################################
Result:
[a, a, a, a, a, b, c, b, d, r, r]
【讨论】:
【参考方案3】:请参阅Javadoc for java.util.Comparator
。上面写着compare()
的方法:
比较它的两个参数的顺序。返回负整数、零或正整数,因为第一个参数小于、等于或大于第二个参数。
对于您的情况,这意味着 compare( 'b', 'c' )
应该返回大于零的值,对于 compare( 'c', 'b' )
应该返回小于零的值,而自然顺序则相反。
但是你的第一个实现(那个错误的那个)只涵盖了compare( 'c', 'b' )
的情况,而不是compare( 'b', 'c' )
,因此该方法将返回默认值。
您的第二个正常工作的实施解决了这个问题。
【讨论】:
以上是关于使用java比较器对字符数组进行排序的主要内容,如果未能解决你的问题,请参考以下文章