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"

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.


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é"
  }
}

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());

@ 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"

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);
}

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.


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);

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);
    }
}

-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);

}

-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


Você deve olhar novamente para> =. O que acontece com "mnmnmnm" como sua string?
Nick Cardoso
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.