Keith L.
Keith L.

Reputation: 11

Unusual String Comparison Java

I have been reading the previous string comparison questions here, and all of them are using an approach that is different from the one I am using. Perhaps their approach is much better, but I want to get this using my approach. I'm trying to write a function that compares two strings and outputs the one that is alphabetically first where capital letters are always considered to precede lower case letters. Java's compareTo method won't work because it ignores the letter case when alphabetizing.

I'm putting a for loop inside a while loop. When the for loop detects one letter of a string to be less than another letter in terms of ASCII value, it should exit the while loop and not complete the for loop, which is supposed to happen. However, the program should be returning "cdf", but it's returning "dbc" even though c precedes d in the alphabet. Why is the program returning 'dbc' and not 'cdf'?

public class Alphabet {
    public static String min_compare(String str1, String str2) {
        int a = 0;
        while (a == 0) {
            for (int i = 0; i < str1.length(); i++) {
                int b = (int) str1.charAt(i);
                int c = (int) str2.charAt(i);
                if (b < c) {
                    a = 1;
                } else if (b > c) {
                    a = 2;
                } else if ((b == c) && (i == (str1.length() - 1))) {
                    a = 1;
                } else {
                    a = 0;
                }
            }
        }
        if (a == 2) {
            return str2;
        } else {
            return str1;
        }
    }

    public static void main(String[] args) {
        String check = min_compare("dbc", "cdf");
        System.out.println(check);
    }
}

Upvotes: 0

Views: 91

Answers (3)

Stephen C
Stephen C

Reputation: 718798

Java's compareTo method won't work because it ignores the letter case when alphabetizing.

That is not correct. The String.compareTo(String) is specified as ordering the string lexicographically, which the javadoc describes as follows:

"This is the definition of lexicographic ordering. If two strings are different, then either they have different characters at some index that is a valid index for both strings, or their lengths are different, or both. If they have different characters at one or more index positions, let k be the smallest such index; then the string whose character at position k has the smaller value, as determined by using the < operator, lexicographically precedes the other string."

If you read that carefully, you will see that it does not ignore case. Also, if you look at the Unicode code charts, you will see that capital letters precede the corresponding lowercase letters ... at least for non-accented letters in the Latin alphabet.

Therefore the compareTo method will order strings according to what you need, provided that you have stated your requirements correctly in the Question.


Looking at your method, I notice that it doesn't implement the standard int compare(String, String) signature. So you can't directly replace it with compareTo.

I can also see a bug: If str2 is a prefix of str1, and str1 is longer, then you will get an exception.

In fact, your method could be rewritten (correctly) as:

  public static String minCompare(String str1, String str2) {
      return str1.compareTo(str2) > 0 ? str2 : str1;
  }

Upvotes: 1

Eugene
Eugene

Reputation: 11075

You mentioned

it should exit the while loop and not complete the for loop

However, you haven't implemented it in your code. I have added breaking nested loop code. Hope it will help. Thx.

public class Alphabet {

    public static String min_compare(String str1, String str2) {

        int a = 0;

        whileloop:
        while (a == 0) {
            for (int i = 0; i < str1.length(); i++) {

                int b = (int) str1.charAt(i);
                int c = (int) str2.charAt(i);
                if (b < c) {
                    a = 1;
                    break whileloop;
                } else if (b > c) {
                    a = 2;
                    break whileloop;
                } else if ((b == c) && (i == (str1.length() - 1))) {
                    a = 1;
                    break whileloop;
                }

                else {

                    a = 0;

                }
            }

        }

        if (a == 2) {
            return str2;
        } else {
            return str1;
        }
    }

    public static void main(String[] args) {

        String check = min_compare("dbc", "cdf");
        System.out.println(check);

    }
}

Upvotes: 1

Scott Hunter
Scott Hunter

Reputation: 49803

  1. There is no need for the while loop; if a is 0 after the for loop finishes, running that for loop again will not result in a different outcome, and thus cause an infinite loop.

  2. You set a for every character of str1; thus, the final value of a will only be determined by the last iteration of the for loop, ignoring what came before.

Upvotes: 1

Related Questions