19

I have a String array:

 String[] str = {"ab" , "fog", "dog", "car", "bed"};
 Arrays.sort(str);
 System.out.println(Arrays.toString(str));

If I use Arrays.sort, the output is:

 [ab, bed, car, dog, fog]

But I need to implement the following ordering:

FCBWHJLOAQUXMPVINTKGZERDYS

I think I need to implement Comparator and override compare method:

 Arrays.sort(str, new Comparator<String>() {

        @Override
        public int compare(String o1, String o2) {
            // TODO Auto-generated method stub
            return 0;
        }
    });

How should I go about solving this?

4
  • 2
    Firstly, you should consider using a character array if your items are always one character in length. Using strings forces more error checking. Commented May 14, 2013 at 10:59
  • @DuncanJones No they are not, this was just an example. I changed them. Thanks Commented May 14, 2013 at 11:02
  • @Sam: so each individual character in the string needs to be sorted by the order and then "normal" string rules apply? How is "AA" sorted relative to "A"? Or "FC" relative to "FB"? Commented May 14, 2013 at 11:05
  • @JoachimSauer I don't know if I got your point correctly. But the order should be: "FC","FB","A","AA" Commented May 14, 2013 at 11:10

4 Answers 4

44
final String ORDER= "FCBWHJLOAQUXMPVINTKGZERDYS";

Arrays.sort(str, new Comparator<String>() {

    @Override
    public int compare(String o1, String o2) {
       return ORDER.indexOf(o1) -  ORDER.indexOf(o2) ;
    }
});

You can also add:

o1.toUpperCase()

If your array is case in-sensitive.


Apparently the OP wants to compare not only letters but strings of letters, so it's a bit more complicated:

    public int compare(String o1, String o2) {
       int pos1 = 0;
       int pos2 = 0;
       for (int i = 0; i < Math.min(o1.length(), o2.length()) && pos1 == pos2; i++) {
          pos1 = ORDER.indexOf(o1.charAt(i));
          pos2 = ORDER.indexOf(o2.charAt(i));
       }

       if (pos1 == pos2 && o1.length() != o2.length()) {
           return o1.length() - o2.length();
       }

       return pos1  - pos2  ;
    }
Sign up to request clarification or add additional context in comments.

8 Comments

careful: upper/lower-case confusion abound.
@MajidL Should that be case in-sensitive?
@MajidL it doesn't seem to give correct result for: {"AA","FB","A","FC"}, it gives [AA, FB, FC, A].
It's not correct. The answer provided would work only if you gave it 1 length string or strings that are a substring of ORDER (for example - JLO)
You could return o1.length() - o2.length() if pos1 - pos2 == 0 to have the shortest word first if they match like A and AA for example.
|
5

I would do something like this:

Put the letters in a HashTable (let's call it orderMap). Key is the letter, value is the index in ORDER.

And then:

Arrays.sort(str, new Comparator<String>() {

    @Override
    public int compare(String o1, String o2) {
        int length = o1.length > o2.length ? o1.length: o2.length
        for(int i = 0; i < length; ++i) {
           int firstLetterIndex = orderMap.get(o1.charAt(i));
           int secondLetterIndex = orderMap.get(o2.charAt(i));

           if(firstLetterIndex == secondLetterIndex) continue;

           // First string has lower index letter (for example F) and the second has higher index letter (for example B) - that means that the first string comes before
           if(firstLetterIndex < secondLetterIndex) return 1;
           else return -1;
        }

        return 0;
    }
});

For making it case-insensitive just do toUpperCase() to both strings at the beginning.

Comments

0

Here you can find usefull link:

Using comparator to make custom sort

In your example instead comparing specific attributes of class you nedd to check possition of char in benchmarked String and base on this check if it's greather/equal/smaller.

Comments

0

Took my time to improve on the selected answer. This is more efficient

public static void customSort(final String order,String[] array){
String[] alphabets={"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","0","1","2","3","4","5","6","7","8","9"};
    String keyword=order;
    for(int g=0; g<alphabets.length; g++){
    String one=alphabets[g];
    if(!keyword.toUpperCase().contains(one)){keyword=keyword+one;}
    }

final String finalKeyword=keyword;
Arrays.sort(array, new Comparator<String>() {

    @Override
   public int compare(String o1, String o2) {
       int pos1 = 0;
       int pos2 = 0;
       for (int i = 0; i < Math.min(o1.length(), o2.length()) && pos1 == pos2; i++) {
          pos1 = finalKeyword.toUpperCase().indexOf(o1.toUpperCase().charAt(i));
          pos2 = finalKeyword.toUpperCase().indexOf(o2.toUpperCase().charAt(i));
       }

       if (pos1 == pos2 && o1.length() != o2.length()) {
           return o1.length() - o2.length();
       }

       return pos1  - pos2  ;
    }
});
//Arrays.sort(array, Collections.reverseOrder());
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.