简体   繁体   English

使用 java 比较器对字符数组进行排序

[英]Sort character array using java comparator

Sort a character array lexicographically with an additional condition that all c's comes before all b's.使用所有 c 都在所有 b 之前的附加条件按字典顺序对字符数组进行排序。 This could be done manually but I want to code it via inbuilt sorting using comparators.这可以手动完成,但我想使用比较器通过内置排序对其进行编码。 The code I wrote -我写的代码 -

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));
}

Gives output: [a, a, a, a, a, b, c, b, d, r, r].给出 output:[a,a,a,a,a,b,c,b,d,r,r]。 The c only comes before one of the b's. c 仅出现在 b 之一之前。 If I change the comparator to the following then it gives the correct output.如果我将比较器更改为以下,那么它会给出正确的 output。

public int compare(Character x, Character y) {
        if(x == 'c' && y == 'b' || x == 'b' && y == 'c') {
            return y - x;
        }
        return x - y;
    }

My question is why in both cases returning "yx" gives the correct answer?我的问题是为什么在这两种情况下返回“yx”都会给出正确答案? If in one case returning "yx" was correct then in the other case shouldn't returning "xy" would have been correct?如果在一种情况下返回“yx”是正确的,那么在另一种情况下不应该返回“xy”是正确的吗? Instead of "yx", returning a -1 or +1 doesn't work either.而不是“yx”,返回 -1 或 +1 也不起作用。 Pl. PL。 explain what is happening internally.解释内部发生的事情。 Thanks!谢谢!

The problem is that if passing 'c' and 'b' makes the comparison return a negative value, then passing 'b' and 'c' should return a positive one (And your first version returns a negative number in that case instead).问题是,如果传递'c''b'使比较返回负值,那么传递'b''c'应该返回一个正值(而你的第一个版本在这种情况下返回一个负数)。 If the function doesn't return consistent results no matter the order of arguments, the sort algorithm is going to produce a garbage order.如果 function 无论 arguments 的顺序如何都没有返回一致的结果,则排序算法将产生垃圾顺序。

Consider this version:考虑这个版本:

    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);
        }
    }

You can add System.out.println() to understand how it work:您可以添加System.out.println()以了解其工作原理:

Code代码

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));
    }
}

Console:安慰:

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]

See the Javadoc for java.util.Comparator .请参阅java.util.Comparator的 Javadoc It says for the method compare() :它对方法compare()说:

Compares its two arguments for order.比较其两个 arguments 的订单。 Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.返回负 integer、零或正 integer,因为第一个参数小于、等于或大于第二个。

For your case, it means that compare( 'b', 'c' ) should return something greater than zero, and for compare( 'c', 'b' ) something less than zero, while the natural order would be the opposite.对于您的情况,这意味着compare( 'b', 'c' )应该返回大于零的值,而对于compare( 'c', 'b' ) ) 应该返回小于零的值,而自然顺序则相反。

But your first implementation (that wrong one) covered only the case compare( 'c', 'b' ) , but not compare( 'b', 'c' ) , so that the method would return the default value then.但是您的第一个实现(那个错误的实现)仅涵盖了案例compare( 'c', 'b' ) ,而不是compare( 'b', 'c' ) ,因此该方法将返回默认值。

Your second and correctly working implementation fixed that.您的第二个正确工作的实施解决了这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM