简体   繁体   中英

How to find Unordered elements from a partially ordered list?

I have a List of which most of the elements are ordered based on a field title . Some of the elements are not ordered. I need to identify which elements are not sorted.

Following class is used to define the elements of the List :

public class Doc {
    String docOid;
    String title;

    private Doc(String docOid, String title) {
        this.docOid = docOid;
        this.title = title;
    }
}

The logic I have written is this:

//List<Doc> docs = given partially ordered list
List<String> oids = new ArrayList<>();

for (int i = 0; i < docs.size(); i++) {
    Doc doc = docs.get(i);
    Doc faildDoc = null;

    for (int j = 0; j < i; j++) {
        Doc prevDoc = docs.get(j);

        if (prevDoc.title != null && doc.title != null) {
            int compare = collator.compare(prevDoc.title, doc.title); // For comparing I have used Collator

            if (compare > 0) {
                faildDoc = prevDoc;
                break;
            }
        }
    }

    if (faildDoc != null) {
        if (!oids.contains(faildDoc.docOid)) {
            oids.add(faildDoc.docOid);
            System.out.println(faildDoc.docOid);
        }
    }                       
}

After the execution when I'm validating the result visually I can see the logic is not yielding the correct result.

Any suggestion would be very helpful.

Following is a sample of the current result:

User Guide Metered Smart //<--Ordered
User Guide, Network Management Card  //<--Ordered
User Guide. GPRS Modem //<--Ordered
Simulation sub-base //<--Un ordered
Vent Hood Installation //<--Ordered
Vented Pullbox Installation //<--Ordered

If the samples were correctly ordered then that would be:

Simulation sub-base 
User Guide Metered Smart 
User Guide, Network Management Card  
User Guide. GPRS Modem 
Vent Hood Installation 
Vented Pullbox Installation 

So I need to find that

Simulation sub-base //<--Un ordered

is not ordered.

You do not need two for loops to find the defects inside your list. You can just move from one correct element to the next correct one. Here is it outlined in pseudo code:

lastCorrect = list.get(0);
for (int i = 1; i < list.size(); i++) {
    current = list.get(i);
    if (inCorrectOrder(lastCorrect, current)) {
        lastCorrect = current;
    } else {
        defects.add(current);
    }
}

Some notes about the solution:

  1. i starts at one, not zero
  2. lastCorrect is initially the first element, because it is always correct
  3. lastCorrect is only moved when the order of this and current element is correct
  4. defects contains all the unsorted elements at the end

This is not well defined what does it mean "unordered" element. Because, for instance, in such sequence it is not clear: is " C " element "unordered" or not?

A E F A B C D

For this particular issue I can suggest you two ways.

First one is quite radical: you have to create a copy of the list, sort it, and then compare each element from old list with an element on the same position in the new list. If elements are different, hence the element is unordered.

In your particular algorithm (though I do not quite understand what exactly you want to achieve with it), you probably have to change the sign in your if statement, or use standard String comparator:

  int compare = doc.title.compareTo(prevDoc.title);

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