简体   繁体   中英

Designing a comparator to order words so that the last letter of each word is the first letter of the next word?

Ok, so I have a program with a part that I need to "Order the words such that the last letter of each item in the list is the first letter of the next item, a sort of chain of words linked together by last and first letters."

The sample input is dog,elephant,giraffe,rhinoceros,tiger and the correct output is dog,giraffe,elephant,tiger,rhinoceros while my output is tiger, rhinoceros, dog, giraffe, elephant.

The comparator is this:

class linkedSort implements Comparator {
    //will return 1 for a match
    //returns 0 if no match

    public int compare(Object t, Object t1) {
        char[] charArr1 = t.toString().toCharArray();
        char[] charArr2 = t1.toString().toCharArray();

        if (charArr1[charArr1.length - 1] == charArr2[0]) {
            return -1;
        } else {
            return 1;
        }
    }
}

Any help would be much appriciated!!

You cannot solve this with a simple comparator and a sort, because the comparison does not define a total order . A total order is one in which the following four properties hold:

  • Reflexivity : x ≤ x is always true.
  • Antisymmetry : If x ≤ y and x ≠ y, then y ≤ x is never true.
  • Transitivity : If x ≤ y and y ≤ z, then x ≤ z
  • Totality : For any x and y, at least one of x ≤ y and y ≤ x holds.

Your order is a not total order. First, it breaks reflexivity: for example, "a" ≤ "a". Second, it breaks antisymmetry: "ease" ≤ "eve" and "eve" ≤ "ease." Third, it breaks transitivity: "east" ≤ "tea" and "tea" ≤ "aver", but "east" ≤ "aver" is false. Finally, it is not total: "east" is not less than "west" and "west" is not less than "east."

To solve this problem, you will need to approach it differently. As a hint, you may want to think of the problem as a graph where the letters are nodes and the words are edges connecting the start and end letters. Can you find a path in this graph that visits every edge exactly once?

Hope this helps!

If you are hoping to do this with sort , then this will not work. A comparator needs to impose a total ordering on the collection, but your requirement is not such a thing.

This is equivalent to this problem: Detecting when matrix multiplication is possible

  1. Create a node for each letter
  2. Join two letters with a directed edge for the corresponding animal (allow multiple edges between same pair of vertices)
  3. Find the Eularian trail

The Comparator approach won't work. Sorting uses only local comparisons, but your problem is a global 'optimisation' one.

To illustrate, here are the actual comparisons from Arrays.sort(array, comparator) . Note that some of the swaps break correct choices made earlier, because they have only local knowledge.

start: dog,elephant,giraffe,rhinoceros,tiger

dog, elephant (swap)

-> elephant,dog,giraffe,rhinoceros,tiger

dog, giraffe (OK)

-> elephant,dog,giraffe,rhinoceros,tiger

giraffe, rhinoceros (swap)

-> elephant,dog,rhinoceros,giraffe,tiger

dog, rhinoceros (swap)

-> elephant,rhinoceros,dog,giraffe,tiger

elephant, rhinoceros (swap)

-> rhinoceros,elephant,dog,giraffe,tiger

giraffe, tiger (swap)

-> rhinoceros,elephant,dog,tiger,giraffe

dog, tiger (swap)

-> rhinoceros,elephant,tiger,dog,giraffe

elephant, tiger (OK)

-> rhinoceros, elephant, tiger, dog, giraffe

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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