Java ordina un array di stringhe (misto a numeri e caratteri) [duplicato]

Sep 18 2020

Sto ordinando un array in Java, i miei input sono {"a3", "a2", "a11", "b1", "b2", "b3", "c3", "c13", "c2"} e Voglio l'output {"a2", "a3", "a11", "b1", "b2", "b3", "c2", "c3", "c13"}

Quello che sto facendo di seguito non restituisce risultati corretti, eventuali suggerimenti / esempi di codice apprezzati

import java.util.Arrays;  

public class Main
{
    public static void main(String[] args) {
        String[] var = {"a3", "a2", "a11", "b1", "b2", "b3", "c3",  "c13", "c2"};  
        Arrays.sort(var);  
        System.out.println(Arrays.toString(var));  
    }
}

Dal codice sopra ricevo l'output [a11, a2, a3, b1, b2, b3, c13, c2, c3]

Risposte

1 WJS Sep 18 2020 at 21:18

Ecco un approccio relativamente semplice. Tuttavia, per qualcosa di simile creerei una classe per contenere separatamente le parti alfa e numeriche e scrivere un comparatore. Quando stampo gli oggetti dovrei semplicemente toString()restituire il valore originale.

Questo è fondamentale. Non controlla le stringhe malformate.

String[] var = {"a3", "a2", "a11", "b1", "b2", "b3", "c3",  "c13", "c2"};  

Comparator<String> comp = (a,b)->{
      // split the strings between the last char and the first digit 
      String[] v1 = a.split("(?<!\\d)(?=\\d)");
      String[] v2 = b.split("(?<!\\d)(?=\\d)");
      
      // convert each integer part to an int.
      int n1 = Integer.valueOf(v1[1]);
      int n2 = Integer.valueOf(v2[1]);

      // compare each and get the result
      int r1 = v1[0].compareTo(v2[0]);
      int r2 = Integer.compare(n1,n2);

      // first sort on r1 (the strings).  If they are equal ( r1 == 0) 
      // then sort on the result of comparing the integers.
      return r1 == 0 ? r2 : r1;
};

Array.sort non accetta un comparatore, quindi è necessario convertire l'array in un elenco e ordinare su quello. Ciò cambierà anche l'array poiché gli array di oggetti eseguono il backup dell'elenco restituito da Arrays.asList.

      
Collections.sort(Arrays.asList(var),comp);
System.out.println(Arrays.toString(var)); 

Stampe

[a2, a3, a11, b1, b2, b3, c2, c3, c13]