0

I'm checking if the strings in my array are arranged in alphabetical order. My codechecker is saying that my code fails to account for some cases, but I'm really not sure how to change it.

EDIT: Apparently my code returns "true" when checking the array "cat ape dog zebra", which is clearly false.

public boolean isSorted()
{
    boolean sorted = true;                          
    for(int i = 0; i < list.size(); i++)
    {
        for(int j = i+1; j < list.size(); j++) 
        {
            if (list.get(i).compareTo(list.get(j)) == 1)
            {
                sorted = false;
            }  
        }  
    }                
    return sorted;
}
rtruszk
  • 3,902
  • 13
  • 36
  • 53
user2577950
  • 31
  • 1
  • 1
  • 3

6 Answers6

7
if (list.get(i).compareTo(list.get(j)) == 1)

The above line is erroneous. The returned value would be positive and not strictly equal to 1.

Try changing to

if (list.get(i).compareTo(list.get(j)) >0)
Shamim Hafiz - MSFT
  • 21,454
  • 43
  • 116
  • 176
4

I guess you're using a instance variable to save a list of String. Try this code where I use Collections.sort():

public boolean isSorted() {

    // Copies all of the elements from one list into another.
    List<String> listSorted = new ArrayList<String>(list);

    // Sorts the new list.
    Collections.sort(listSorted);

    // Check if both of list are equals.
    return listSorted.equals(list);
}
amatellanes
  • 3,645
  • 2
  • 17
  • 19
  • 1
    Just create a new list from the old, no need to walk through adding each element. List newList = new ArrayList(oldList); – Chris Kessel Jul 12 '13 at 21:46
  • More importantly, this is a horribly inefficient approach. Checking sort should require linear time and constant additional space. This requires nlog(n) time and linear additional space. As others have pointed out, @user2577950's code has two flaws. The incorrect comparison for compareTo()'s output and not short-circuiting when finding a mismatch. – GinoA Jul 12 '13 at 22:01
2

It's far easier than it looks: just iterate over the list, checking if adjacent elements are in the right order. If all adjacent pairs are in order, then the whole list is.

public boolean isSorted()
{
    for(int a=0;a<list.size()-1;a++)
    {
        if(list.get(a).compareTo(list.get(a+1))>0)
        {
            return false;
        }
    }
    return true;
}
Ermir
  • 1,391
  • 11
  • 25
  • As noted by Shamin, would be better to write `list.get(i).compareTo(list.get(j)) >0` – Barranka Jul 12 '13 at 21:27
  • Another advantage of this piece of code is that it exits in the moment it finds an unsorted element. The OP code reads the full list, which can be unnecesary: If one entry is unsorted, then the full list is unsorted – Barranka Jul 12 '13 at 21:30
  • @Barranka The OP's answer actually only returns the comparison of the last two entries. – GinoA Jul 12 '13 at 22:03
0

Using String.compareTo() is a very easy way to do it.

String.compareTo() returns a negative number if the string precedes the argument of the method, 0 if it is the same, and a positive number if the string comes after the argument of the method

The way you did it:

if (list.get(i).compareTo(list.get(j)) == 1)

Is very close, but it should be

if (list.get(i).compareTo(list.get(j)) > 0)

You could use that alongside of a comparator to quickly sort, or in your case check to see if it is sorted

boolean isSorted(String[] words) {

    for (int i = 0; i < words.length()-1; i++) {
        if (words[i].compareTo(words[i+1] >= 0) {
            return false;
        }
    }
    return true;
}

Or if you wanted to sort them, this would work:

Collections.sort(fooList,
             new Comparator<String>()
             {
                 public int compare(String s1, String s2)
                 {
                     return s1.compareTo(s2);
                 }        
             });

Source

Or to return true or false

Community
  • 1
  • 1
Stephan
  • 16,509
  • 7
  • 35
  • 61
0

compareTo() returns a positive value (not necessarily 1) if the string on the left-hand-side is "greater" than the one on the right. Thus, you need to change the condition from == 1 to >= 1.

Also, you don't need a second loop (j) that runs over all elements. You just need to compare two consecutive elements, as follows:

public boolean isSorted()  {
    for(int i = 1; i < list.size(); i++) 
        if (list.get(i).compareTo(list.get(i - 1)) >= 1) 
          return false;
    return true;
}
Itay Maman
  • 30,277
  • 10
  • 88
  • 118
0

I know it's a Java question, but here's how I ended up implementing this in Kotlin very succinctly:

myList.zipWithNext { a, b ->
    if (a > b) {
         fail("Expected a sorted list, but $a > $b")
    }
}
Rik
  • 790
  • 8
  • 11