Comparing Strings lexicographically new approach fails for one test case

536 views Asked by At

I was asked to check whether String a is lexicographically larger String b. So even before thinking about compareTo() method I got a new idea.

  1. Take the minimum of the lengths of both a & b.
  2. Iterate a for loop till that minimum length and store the sum of ascii's of each characters in both a & b separately.
  3. Compare the ascii's to print the result.

Here is my code

private static void isInLexicographicOrder(String a, String b) {
    char[] arr1 = a.toCharArray();
    int asciCount1 = 0;

    char[] arr2 = b.toCharArray();
    int asciCount2 = 0;

    long asciLength = (a.length() < b.length()) ? a.length() : b.length();
    for(int i=0; i<asciLength; i++) {
        asciCount1 += arr1[i];
        asciCount2 += arr2[i];
    }

    if(asciCount1 < asciCount2) {
        System.out.println("In Lexicographic Order");
    }
    else {
        System.out.println("Not In Lexicographic Order");
    }

}

It is working fine for many inputs I provided, then I found this link String Comparison in Java, so for confirmation I used compare to method in my code.

System.out.println((a.compareTo(b)) < 0 ? "In Lexicographic Order" : "Not In Lexicographic Order");

Now when I submitted the code the other website is saying that the code is failing for one test case

Sample input

vuut
vuuuuu

They are want output to come as No ie, Not In Lexicographic Order. But my logic and the compareTo() logic says In Lexicographic Order. So whats wrong, Is my logic is completely correct?

This is the link where I got the Question. Sorry if I'm wrong

2

There are 2 answers

3
Eran On BEST ANSWER

Your logic is not correct. Comparing the sums of the characters is wrong, since "bab", "abb" and "bba" will have the same value, but that tells you nothing regarding which of them comes first lexicographicaly.

You should compare each pair of characters separately. The first time you encounter a pair of characters not equal to each other, the one with the lower value belongs to the String that should come first.

for(int i=0; i<asciLength; i++) {
    if (arr1[i] > arr2[i]) {
        System.out.println("Not In Lexicographic Order");
        return;
    } else if (arr1[i] < arr2[i]) {
        System.out.println("In Lexicographic Order");
        return;
    }
}
// at this point we know that the Strings are either equal or one 
// is fully contained in the other. The shorter String must come first
if (arr1.length <= arr2.length) {
    System.out.println("In Lexicographic Order");
} else {
    System.out.println("Not In Lexicographic Order");
} 
1
Lothar On

The comareTo method iterates over the characters of the two strings until it reaches a position where the two characters differ. The return-value is the difference between the two codepoint values.

Your implemenation adds all the codepoints to a sum and returns the difference of the result of this addition.

Try your method with the values abcd and dcba. I expect your method to return 0instead of a negative number