Sort String list in pre-defined custom ordering

吃可爱长大的小学妹 提交于 2019-12-02 23:26:30

问题


I have this project in which the program asks the user how many times it should run. During each run a list is created and elements are added. These elements in the array are sorted not alphabetically but sorted in the following order:

q,w,e,r,t,y,u,i,o,p,l,k,j,h,g,f,d,s,a,z,x,c,v,b,n,m

I am able to run my program up to the point where it accepts input, but I don't know what to do next...

Sample input

2

3
what
are
you

2
sad
set

Sample Output

what
you
are

set
sad

Here is my code:

import java.util.*;


public class WeirdWritings {

    public static void main(String[] args) {
        int data,word,ctr,i,ii;
        char[] rLetter = {'Q','W','E','R','T','Y','U','I','O','P','L','K','J','H','G','F','D','S','A','Z','X','C','V','B','N','M'};
        String entry;

        Scanner s = new Scanner(System.in);

        data=s.nextInt();
        for (ctr=0;ctr<rLetter.length;ctr++)
            System.out.print(rLetter[ctr]);
        System.out.println();

        for (ii = 0; ii<data; ii++) {
            word=s.nextInt();
            List<String> array_ii = new ArrayList<String>();
            for(i=0; i<word; i++) {
                entry=s.next();
                array_ii.add(entry);
            }
        }

    }
}

adding the comparator to it to finish it

public class MyComparator implements Comparator {

private int[] charRank;

public MyComparator() {
    char[] charOrder = {'Q','W','E','R','T','Y','U','I','O','P','L','K','J','H','G','F','D','S','A','Z','X','C','V','B','N','M'};
    this.charRank = new int[26];
    for(int i=0; i<25; i++) {
        this.charRank[charToInt(charOrder[i])] = i; 
    }
}

public int compare(String s1, String s2) {
    // returns
    // Positive integer if s1 greater than s2
    // 0 if s1 = s2
    // Negative integer if s1 smaller than s2
    s1 = s1.toUpperCase();
    s2 = s2.toUpperCase();
    int l = Math.min(s1.length(), s2.length());
    int charComp;
    for(int i=0; i<l; i++) {
        charComp = this.charRank[charToInt(s1.charAt(i))] - charRank[charToInt(s2.charAt(i))];
        if(charComp != 0)
            return charComp;
    }
    return s1.length() - s2.length();
}

//works for c between 'A' and 'Z' - upper case letters
private static int charToInt(char c) {
    return c - 65;
}

//works for 0<=i<=25
private static char intToChar(int i) {
    return (char) (i + 65);
}

public static void main(String[] args) {
    int data,word,ctr,i,ii;
    char[] rLetter = {'Q','W','E','R','T','Y','U','I','O','P','L','K','J','H','G','F','D','S','A','Z','X','C','V','B','N','M'};
    String entry;

    Scanner s = new Scanner(System.in);

    data=s.nextInt();
    for (ctr=0;ctr<rLetter.length;ctr++)
        System.out.print(rLetter[ctr]);
    System.out.println();

    for (ii = 0; ii<data; ii++) {
        word=s.nextInt();
        String[] array_ii = new String[word];
        for(i=0; i<word; i++) {
            entry=s.next();
            array_ii[i]=(entry);
        }
        Arrays.sort(array_ii, new MyComparator());
        for(i=0; i<word; i++) {
            System.out.println(array_ii[i]);
        }
    }



}

}


回答1:


You can build your own Comparator:

import java.util.Comparator;

public class MyComparator implements Comparator<String> {

    private int[] charRank;

    public MyComparator() {
        char[] charOrder = {'Q','W','E','R','T','Y','U','I','O','P','L','K','J','H','G','F','D','S','A','Z','X','C','V','B','N','M'};
        this.charRank = new int[26];
        for(int i=0; i<25; i++) {
            this.charRank[charToInt(charOrder[i])] = i; 
        }
    }

    public int compare(String s1, String s2) {
        // returns
        // Positive integer if s1 greater than s2
        // 0 if s1 = s2
        // Negative integer if s1 smaller than s2
        s1 = s1.toUpperCase();
        s2 = s2.toUpperCase();
        int l = Math.min(s1.length(), s2.length());
        int charComp;
        for(int i=0; i<l; i++) {
            charComp = this.charRank[charToInt(s1.charAt(i))] - charRank[charToInt(s2.charAt(i))];
            if(charComp != 0)
                return charComp;
        }
        return s1.length() - s2.length();
    }

    //works for c between 'A' and 'Z' - upper case letters
    private static int charToInt(char c) {
        return c - 65;
    }

    //works for 0<=i<=25
    private static char intToChar(int i) {
        return (char) (i + 65);
    }

}

Then, you just have to run:

Arrays.sort(entryArray, new MyComparator());

Some explanations now.

The constructor of MyComparator builds an array of ranks for each of your letter. In practice it will begin with {18, 23, 21, ... } because 'A' is in the 18th place, 'B' in the 23rd...

Then, when you compare two strings s1 and s2, characters are compared in the lexicographic order one by one.

  • Imagine the first n characters are identical, and now, you compare c1 and c2. If the rank of c1 is lower than then rank of c2, then you have to return a negative integer since s1 comes before s2 in the lexicographic order (s1 is smaller than s2). If the rank of c1 is greater than the rank of c2, it is the contrary. If both ranks are equals c1 and c2 are equals and you have to look at the next character.
  • If you reach the end of one string, then either the two string are equals, either one string is the prefix of another. In each case, it is enough to compare the lengths of the strings: if s1 is shorter, it comes first in the lexicographic order, it is smaller, you have to return a negative integer.

And here you go. I hope it was what you were waiting for.

@Edit: the s1 = s1.toUpperCase() is just to avoid the pain to distinguish upper and lower case letters. If you prefer to work with lower case letters, just change it to s1 = s1.toLowerCase(), change the method intToChar to return c-97 (ascii code for a lower case 'a') and naturally, specify the charOrder array in the constructor using lower case letters.



来源:https://stackoverflow.com/questions/25508552/sort-string-list-in-pre-defined-custom-ordering

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!