Classifique uma única String em Java

131

Existe uma maneira nativa de classificar uma String pelo seu conteúdo em java? Por exemplo

String s = "edcba"  ->  "abcde"
starblue
fonte

Respostas:

215

toCharArrayseguido por Arrays.sortuma chamada do construtor String:

import java.util.Arrays;

public class Test
{
    public static void main(String[] args)
    {
        String original = "edcba";
        char[] chars = original.toCharArray();
        Arrays.sort(chars);
        String sorted = new String(chars);
        System.out.println(sorted);
    }
}

EDIT: Como o tackline aponta, isso falhará se a string contiver pares substitutos ou mesmo caracteres compostos (acento + e como caracteres separados) etc. Nesse ponto, fica muito mais difícil ... espero que você não precise disso :) Além disso, isso é apenas ordenar por ordinal, sem levar em maiúsculas, sotaques ou qualquer outra coisa em consideração.

Jon Skeet
fonte
2
A maneira correta seria classificar os pontos do código. Infelizmente não há String.toCodePointArray. (Que ordem devemos ser classificação em, btw?)
Tom Hawtin - tackline
1
O projeto ICU descreve um método de classificação UTF-16 com ordem de ponto de código: icu-project.org/docs/papers/utf16_code_point_order.html . Eu não acho que Arrays.sort destruirá quaisquer caracteres suplementares devido à maneira como os intervalos são definidos, mas não me cite.
McDowell
1
Talvez não destrua nada, mas a ordem de classificação não é ideal se você quiser levar em conta letras maiúsculas e sotaques, por exemplo. Esse algoritmo classificará "éDedCBcbAàa" como "ABCDabcdeàé", enquanto que, por exemplo, na localidade em inglês (EUA), seria mais desejável obter "aAàbBcCdDeé".
317 eljenso
1
@YiweiG E, neste caso, a resposta é: definitivamente não. sortedjá é um String... o que você esperaria que toString()ele fizesse?
Jon Skeet
1
@Hengameh: Você está classificando uma matriz de caracteres, mas depois a ignorando. Você gostariachar[] c = s.toCharArray(); Arrays.sort(c); String sorted = new String(c);
Jon Skeet
49

Não, não há método String incorporado. Você pode convertê-lo em uma matriz de caracteres, classificá-lo usando Arrays.sort e convertê-lo novamente em uma String.

String test= "edcba";
char[] ar = test.toCharArray();
Arrays.sort(ar);
String sorted = String.valueOf(ar);

Ou, quando você deseja lidar corretamente com itens específicos do código do idioma, como caracteres maiúsculos e acentuados:

import java.text.Collator;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Locale;

public class Test
{
  public static void main(String[] args)
  {
    Collator collator = Collator.getInstance(new Locale("fr", "FR"));
    String original = "éDedCBcbAàa";
    String[] split = original.split("");
    Arrays.sort(split, collator);
    String sorted = "";
    for (int i = 0; i < split.length; i++)
    {
      sorted += split[i];
    }
    System.out.println(sorted); // "aAàbBcCdDeé"
  }
}
eljenso
fonte
FYI: esse método dividirá pontos de código de 32 bits em caracteres Unicode de dois com um valor maior que 0xFFFF, criando cadeias com valores inválidos. Não é um problema para o francês, mas pode causar problemas para alguns locais.
224 McDowell
Veja Character.isHighSurrogate (char)
McDowell
1
De alguma forma eu acho que isso vai fazer ... a menos que ele quer classificar Cordas contendo Swahili ou algo :)
eljenso
3
"Acho que isso funcionará ... a menos que ele queira classificar Strings contendo suaíli" - posso ver o slogan - Unicode: quando você deseja uma maneira fácil de localizar e traduzir seus aplicativos para alguns idiomas. Bzzt. Falhou. Fazer a coisa quase certa significa que você quase não tem um bug para corrigir mais tarde.
Jonas Kolker
@ Jonas, eu disse que acho , a menos que o OP queira especificar que é absolutamente necessário apoiar o suaíli. Eu até prefiro a solução simples sem a localidade, novamente, a menos que o OP afirme que não é suficiente. Já ouviu falar do princípio YAGNI?
317 eljenso
32

No Java 8, isso pode ser feito com:

String s = "edcba".chars()
    .sorted()
    .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
    .toString();

Uma alternativa ligeiramente mais curta que funciona com um fluxo de strings de comprimento um (cada caractere na string não classificada é convertida em uma string no fluxo) é:

String sorted =
    Stream.of("edcba".split(""))
        .sorted()
        .collect(Collectors.joining());
Marcin
fonte
@ Dennis sobre qual exatamente e por quê?
Marcin
O primeiro bit em que você tenta classificar uma String. Parece bom, mas quando o executei em um grande conjunto de dados, foi um pouco mais lento em comparação com a resposta de Jon Skeets.
Dennis
18

Converta em array de caracteresClassificarConverter novamente em String :

String s = "edcba";
char[] c = s.toCharArray();        // convert to array of chars 
java.util.Arrays.sort(c);          // sort
String newString = new String(c);  // convert back to String
System.out.println(newString);     // "abcde"
Maroun
fonte
Qual foi o ponto em adicionar esta resposta 4 anos após outras pessoas postado pelo menos 3 respostas idênticas
Nick Cardoso
1
@NickCardoso Eu realmente não me lembro, você está me perguntando sobre uma resposta que eu publiquei nos meus estágios iniciais no Stack Overflow. Você realmente está esperando uma explicação sobre isso?
Maron
@NickCardoso Estou NÃO tentando fornecer uma desculpa para você em tudo. Seu comentário e voto negativo não mudarão nada por enquanto. Isso é o que eu decidi há quatro anos, não vejo qual é o ponto de trazer isso até agora :)
Maroun
16

Uma abordagem mais bruta sem usar o método sort Arrays.sort. Isso está usando classificação de inserção.

public static void main(String[] args){
    String wordSt="watch";
    char[] word=wordSt.toCharArray();

    for(int i=0;i<(word.length-1);i++){
        for(int j=i+1;j>0;j--){
            if(word[j]<word[j-1]){
                char temp=word[j-1];
                word[j-1]=word[j];
                word[j]=temp;
            }
        }
    }
    wordSt=String.valueOf(word);
    System.out.println(wordSt);
}
de novo
fonte
1
a pergunta foi feita de maneira nativa em java, sem usar nenhum outro algoritmo de classificação.
Vikrant Goel
1
Votada porque era uma solução útil, não porque era a resposta solicitada.
Chris
1
@VikrantGoel "Caminho nativo em java" - o que não é nativo nessa abordagem? não vejo requisitos de terceiros. Você?
Nick Cardoso
Essa deve ser a resposta correta. Como o @NickCardoso disse ... nada é mais "Caminho nativo em java" do que isso.
Mariano Zorrilla
14
    String a ="dgfa";
    char [] c = a.toCharArray();
    Arrays.sort(c);
    return new String(c);

Observe que isso não funcionará conforme o esperado se for uma String com maiúsculas e minúsculas (será colocada em maiúscula antes de minúscula). Você pode passar um comparador para o método Sort para alterar isso.

amit
fonte
1
você precisa importar java.util.Arrays; ou então não vai funcionar
hopper
3

Procedimento:

  1. Inicialmente converta a string em array de caracteres
  2. Em seguida, classifique a matriz de caracteres
  3. Converta a matriz de caracteres em string
  4. Imprimir a sequência

Fragmento de código:

    String input = "world";
    char[] arr = input.toCharArray();
    Arrays.sort(arr);
    String sorted = new String(arr);
    System.out.println(sorted);
rashedcs
fonte
Isso é uma piada? Postando respostas idênticas a uma pergunta de 8 anos? Que preguiça.
Nick Cardoso
Eu sou ignorante. Me perdoe.
Rashedcs
2

Pergunta: classificar uma string em java

public class SortAStringInJava {
    public static void main(String[] args) {

        String str = "Protijayi";
// Method 1
        str = str.chars() // IntStream
                .sorted().collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();

        System.out.println(str);
        // Method 2
        str = Stream.of(str.split(" ")).sorted().collect(Collectors.joining());
        System.out.println(str);
    }
}
Soudipta Dutta
fonte
-1
public static void main(String[] args) {
    String str = "helloword";   
    char[] arr;
    List<Character> l = new ArrayList<Character>();
    for (int i = 0; i < str.length(); i++) {
        arr = str.toCharArray();
        l.add(arr[i]);

    }
    Collections.sort(l);
    str = l.toString();
    System.out.println(str);
    str = str.replaceAll("\\[", "").replaceAll("\\]", "")
            .replaceAll("[,]", "");
    System.out.println(str);

}
Tarun Jadhav
fonte
-2

Sem usar coleções em Java:

import java.util.Scanner;

public class SortingaString {
    public static String Sort(String s1)
    {
        char ch[]=s1.toCharArray();         
        String res=" ";
        
        for(int i=0; i<ch.length ; i++)
        {
            for(int j=i+1;j<ch.length; j++)
            {
                if(ch[i]>=ch[j])
                {
                    char m=ch[i];
                    ch[i]=ch[j];
                    ch[j]=m;
                }
            }
            
            res=res+ch[i];
            
        }

        return res;
    }

    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        System.out.println("enter the string");
        
        String s1=sc.next();
        String ans=Sort( s1);
        
        System.out.println("after sorting=="+ans);
    }
}

Resultado:

insira a string ==

Ordenação

após a classificação == ginorst

naveen prasanna
fonte
Você deve olhar novamente para> =. O que acontece com "mnmnmnm" como sua string?
Nick Cardoso