简体   繁体   中英

Java - How to sort a 2D array numerically and alphabetically?

I have a 2D array of Strings. All the columns are String of numbers. I need to sort the array in descending order by the columns and when the columns are the same, I need to sort them alphabetically by the words in the row.

Example:

input = "Practice makes perfect. you'll only get Perfect by practice. just practice!"

output: [ ["practice", "3"], ["perfect", "2"],
      ["by", "1"], ["get", "1"], ["just", "1"],
      ["makes", "1"], ["only", "1"], ["youll", "1"]  ]

So I've done all the work, like parsing the input and counting the occurrence of words.

So, I'm using a Comparator to sort them but it's not working. My 2D array is called result and here is the code:

Arrays.sort(result, new Comparator<String[]>() {
    @Override
    public int compare(String[] a, String[] b) {
      int diff = b[1].compareTo(a[1]);
      if (diff == 0) {
        diff = b[0].compareTo(a[0]);
      }
      return diff;
    }
  }); 

They get sorted by occurrence just fine but then when the cols are the same there is no order to the words.

Thanks.

I think you want to solve below problem : Whatever input string, you want to make a 2d array where each unique words and their occurrence count store.

Now you want to sort that 2D Array on the basis of word's occurrence count in descending order and if occurrence count matched among multiple word's occurrence count then sort them in descending order on the basis of alphabetically among them.

I am sorted Array without Comparator , It may be help you .

private static void sort2DArray(String[][] string2DArray) {
    int maxInt;
    String maxKey;
    String maxValue;
    int flag = 0;

    /* Sort the 2D Array */
    for (int m = 0; m < string2DArray.length; m++) {
        maxInt = Integer.parseInt(string2DArray[m][1]);
        for (int n = 0; n < string2DArray.length; n++) {

            /* swap on the basis of word's occurrences */
            if (maxInt > Integer.parseInt(string2DArray[n][1])) {
                maxKey = string2DArray[m][0];
                maxValue = string2DArray[m][1];
                string2DArray[m][0] = string2DArray[n][0];
                string2DArray[m][1] = string2DArray[n][1];
                string2DArray[n][0] = maxKey;
                string2DArray[n][1] = maxValue;
                maxInt = Integer.parseInt(string2DArray[n][1]);
            } else {

                /* swap on the basis of word */
                if (maxInt == Integer.parseInt(string2DArray[n][1])) {
                    flag = string2DArray[m][0].compareToIgnoreCase(string2DArray[n][0]);
                    if (flag > 0) {
                        maxKey = string2DArray[m][0];
                        maxValue = string2DArray[m][1];
                        string2DArray[m][0] = string2DArray[n][0];
                        string2DArray[m][1] = string2DArray[n][1];
                        string2DArray[n][0] = maxKey;
                        string2DArray[n][1] = maxValue;
                    }
                }
            }
        }
    }
}

For descending order of occurences and alphabetic order of words you can use a comparator of the below form

Arrays.sort(arr,(a,b) -> a[1].compareTo(b[1])==0? a[0].compareTo(b[0]) : 0-(a[1].compareTo(b[1])));

I am using a lambda expression, which basically checks if the occurences are equal, and if so compares the values of the words, else it returns the comparison of the occurences with altered sign (to get them in descending order).

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