简体   繁体   English

自定义比较器<String> java中的问题

[英]Custom comparator<String> issue in java

I am currently making a natural sorting algorithm in Java.我目前正在用 Java 制作自然排序算法。 And the requirement is to make it run fast.并且要求是让它跑得快。 Given an input String list, [1!, 10!, 100, 100!, 2].给定一个输入字符串列表,[1!, 10!, 100, 100!, 2]。 The expected output order is [1!, 2, 10!,100, 100!].预期的输出顺序是 [1!, 2, 10!,100, 100!]。 As you can see they sort digit number first and then compare the value.如您所见,它们首先对数字进行排序,然后再比较值。 However it is giving me headache when designing the cases.然而,在设计案例时让我头疼。

Here is my thoughts when designing this problem.这是我在设计这个问题时的想法。

Given String a , b .给定字符串ab
(Edit: The input values could be 100!90!10!1234 with multiple "!" inside.Sorry for not mentioning earlier.The input will have english letter as well. But current version could handle it like a boss) (编辑:输入值可能是 100!90!10!1234 里面有多个“!”。抱歉没有提前提到。输入也会有英文字母。但当前版本可以像老板一样处理它)

I create four index (ind_a1, ind_a2, ind_b1, ind_b2)我创建了四个索引(ind_a1, ind_a2, ind_b1, ind_b2)

Case 1: If either ind_a1 or ind_b1 touch !情况 1:如果ind_a1ind_b1触摸! , then return -1 ,然后返回-1

Case 2: If either ind_a1 or ind_b1 touch the end of the string - 1 return -1 (The current problem occurs right here in Case 2)情况 2:如果ind_a1ind_b1接触到字符串的末尾 - 1 返回-1 (当前问题发生在情况 2 中)

Case 3: When both index touch !情况 3:当两个索引都接触! , ,

Case 3.1: Check if a.substring(ind_a2, ind_a1) == (b.substring(ind_b2, ind_b1) If they are equal means the previous values are the same. For example: 1258!100 and 1258!10 . a.substring(ind_a2, ind_a1) = (b.substring(ind_b2, ind_b1) = 1258案例 3.1:检查a.substring(ind_a2, ind_a1) == (b.substring(ind_b2, ind_b1)如果它们相等则表示之前的值相同。例如: 1258!1001258!10 a.substring(ind_a2, ind_a1) = (b.substring(ind_b2, ind_b1) = 1258

Case 3.2:If they are not equal, then it just returns the previous compare values. Case 3.2:如果不相等,则只返回之前的比较值。

Here is my full code.这是我的完整代码。

public int compare(String a, String b) {
        int ind_a1 = 0 ,ind_a2 = 0;
        int ind_b1 = 0 ,ind_b2 = 0;
        int length_a = a.length();
        int length_b = b.length();
        int result = a.compareTo(b);
        char char_a, char_b;


        while(true)
        {
            char_a = a.charAt(ind_a1);
            char_b = b.charAt(ind_b1);
            //check if a or b is an empty String
            if(length_a == 0 || length_b ==0) {
                return length_a - length_b;
            }

            //Case 1)
            if(char_a == '!' && char_b != '!') {
                return -1;
            }
            if(char_b == '!' && char_a != '!') {
                return +1;
            }
            //Case 2: I NEED HELP HERE
            if(ind_a1 == length_a-1 || ind_b1 == length_b-1 ) {
                return length_a - length_b;
            }

            //Case 2 corner case, if both string has same length
            if(length_a == length_b) {
                return result;
            }

            //Case 3, if both index touch "!"   
            if(char_a =='!' && char_b == '!' ) {
                //Case 3.1
                if(a.substring(ind_a2, ind_a1) == (b.substring(ind_b2, ind_b1))) {
                    ind_a2 = ind_a1;
                    ind_b2 = ind_b1;
                }
                //Case 3.2
                else {
                    return a.substring(ind_a2,ind_a1).compareTo(b.substring(ind_b2,ind_b1));
                }                       
            }       
            ind_a1++;
            ind_b1++;
        }


    }

}

The current output order is [2, 1!, 10!, 100, 100!].当前输出顺序为 [2, 1!, 10!, 100, 100!]。 I know it doesnt work because 2 has less index then 1!我知道它不起作用,因为 2 的索引比 1 少! so it will return -1.所以它会返回-1。 However is there anyway to adjust the code (or make it better, I would be so grateful) to make it work ?但是,无论如何要调整代码(或使其更好,我将不胜感激)使其工作?

(Example, Given input of [A5,a5,A5!,a5!,!A,!a,A,a,1,!] (例如,给定输入 [A5,a5,A5!,a5!,!A,!a,A,a,1,!]

The output should be [!, !A, !a, 1, A, a, A5, A5!, a5!输出应该是 [!, !A, !a, 1, A, a, A5, A5!, a5! ]) ])

public static void main(String... S) {
    List a = Arrays.asList("1!", "10!", "100!", "100", "2");
    Collections.sort(a, new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            int oo1 = 0;
            int oo2 = 0;

            if (o1.contains("!")) {
                oo1 = 1;
                o1 = o1.replace("!", "");
            }

            if (o2.contains("!")) {
                oo2 = 1;
                o2 = o2.replace("!", "");
            }

            int result = (Integer.valueOf(o1) - Integer.valueOf(o2));

            return result == 0 ? oo1 - oo2 : result;
        }
    });
    System.out.println(a);

} }

As per comment根据评论

@Psingh We dont have to deal with "!!!!" @Psingh 我们不必处理“!!!!” scenario.设想。 The expected value should be [2, A, 1!, 10!, 100, 100!期望值应该是 [2, A, 1!, 10!, 100, 100! ] ]

public static void main(String... S) {
    List a = Arrays.asList("1!", "1!!", "10!", "100!", "100", "2", "A");
    Collections.sort(a, new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            int ooo1 = 0;
            int ooo2 = 0;

            for (char i : o1.toCharArray()) {
                ooo1 += (int) i;
            }
            for (char i : o2.toCharArray()) {
                ooo2 += (int) i;
            }
            return ooo1 - ooo2;
        }
    });
    System.out.println(a);
}

Edit: Added the test case you mentioned before, to point out there inconsistency.编辑:添加了您之前提到的测试用例,以指出不一致之处。


Give this a try.试试这个。 I am still not sure whether this covers all your input requirements, but works for the following testcases:我仍然不确定这是否涵盖了您的所有输入要求,但适用于以下测试用例:

input: [A5,a5,A5!,a5!,!A,!a,A,a,1,!]
expected output: [!, !A, !a, 1, A, a, A5, a5, A5!, a5!]
input: [1!, 1!!, 10!, 100!, 100, 2, A]
expected output: [2, A, 1!, 1!!, 10!, 100, 100!]

However for this testcase:但是对于这个测试用例:

input: [1!, 10!, 100, 100!, 2 , 2!, 22!, 22, 100 , 3]
expected output: [1!, 2, 2!, 3, 22, 22!, 100, 100!]

the output is different.输出是不同的。 You expectations seem to be inconsistent in this case, as this example has a different ordering for the elements 2 & 1!.在这种情况下,您的期望似乎不一致,因为此示例对元素 2 和 1! 具有不同的顺序

As long as that is the case there isnt really any point in trying to answer your question.只要是这种情况,尝试回答您的问题就没有任何意义。


    Collections.sort(a, new Comparator<String>() {

        @Override
        public int compare(String o1, String o2) {

            int minSize = Math.min(o1.length(), o2.length());
            int index = 0;

            while (index < minSize) {

                char c1 = o1.charAt(index);
                char c2 = o2.charAt(index);

                if (c1 != c2) {

                    if (o1.length() == o2.length()) {
                        return c1 - c2;
                    }

                    if (c1 == '!') {
                        return -1;
                    } else if (c2 == '!') {
                        return 1;
                    }

                    return o1.length() - o2.length();
                }

                index++;
            }

            if (o1.length() == index) {
                if (o2.length() == index) {
                    return 0;
                }

                return -1;
            } else {
                return 1;
            }
        }
    });

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

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