3

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!!

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
Samuel French
  • 665
  • 3
  • 11
  • 22
  • Your first problem is that your comments say returns 1 or 0 and the method returns -1 or 1. Also, as @SLaks said, please describe what you have tried and how it is failing/performing unexpectedly. – Thomas Feb 15 '12 at 21:53

4 Answers4

10

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!

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
3

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.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
1

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
Community
  • 1
  • 1
ElKamina
  • 7,747
  • 28
  • 43
  • I don't think his graph is Eularian. I think he wants a Hamiltonian circuit that visits each word once (however if the end of the word trail need not connect to the start of the word trail, then he needs the longest path that doesn't use the same node twice, where words are nodes) – Rusty Rob Feb 15 '12 at 23:25
  • @robertking It depends on how you formulate it. If you formulate words as nodes you need to find the hamiltonian circuit, which is a NP complete problem. If you formulate words as edges, then you need to find the eularian path which is close to linear time. – ElKamina Feb 15 '12 at 23:30
  • I see, you said Eularian trail rather than eularian circuit. Still I don't think you need to traverse all edges. e.g. "ant,antelope, ,toad,enigma", enigma would have an edge to both ant and antelope but you would only use one of those edges – Rusty Rob Feb 15 '12 at 23:41
  • @robertking Once again, I am NOT drawing edges between words, but words are themselves edges. Eg. ant=> edge between 'a' and 't' , antelope => edge between 'a' and 'e' ... and so on. In the final trail you need to have all the words=> all the edges. – ElKamina Feb 15 '12 at 23:48
  • right, but art and ant would both give an edge between a and t, but one word would be lost – Rusty Rob Feb 16 '12 at 00:06
  • 1
    @robertking Yes. That is why you should allow for multiple edges between same set of vertices. If you don't want to do it, then use a temporary vertex, the complexity will remain same. – ElKamina Feb 16 '12 at 00:31
  • thanks ElKamina, I forgot you could have multiple edges between two nodes. – Rusty Rob Feb 16 '12 at 02:54
0

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
DNA
  • 42,007
  • 12
  • 107
  • 146