Sortuj pojedynczy ciąg w Javie

133

Czy istnieje natywny sposób sortowania ciągu znaków według jego zawartości w Javie? Na przykład

String s = "edcba"  ->  "abcde"
starblue
źródło

Odpowiedzi:

219

toCharArraypo którym Arrays.sortnastępuje wywołanie konstruktora 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);
    }
}

EDYCJA: Jak wskazuje tackline, to się nie powiedzie, jeśli ciąg zawiera pary zastępcze lub rzeczywiście złożone znaki (akcent + e jako oddzielne znaki) itp. W tym momencie robi się dużo trudniej ... miejmy nadzieję, że nie potrzebujesz tego :) Ponadto jest to po prostu porządkowanie według liczby porządkowej, bez uwzględniania wielkich liter, akcentów ani czegokolwiek innego.

Jon Skeet
źródło
2
Prawidłowym sposobem byłoby posortowanie punktów kodowych. Niestety nie ma String.toCodePointArray. (W jakiej kolejności powinniśmy się sortować, przy okazji?)
Tom Hawtin - tackline
1
Projekt ICU opisuje metodę sortowania kolejności punktów kodowych UTF-16: icu-project.org/docs/papers/utf16_code_point_order.html . Nie sądzę, aby Arrays.sort zniszczył jakiekolwiek dodatkowe znaki ze względu na sposób definiowania zakresów, ale nie cytuj mnie.
McDowell
1
Może niczego nie zniszczy, ale kolejność sortowania nie jest optymalna, jeśli chcesz wziąć pod uwagę na przykład wielkie litery i akcenty. Algorytm ten posortuje „éDedCBcbAàa” jako „ABCDabcdeàé”, podczas gdy na przykład w języku angielskim (USA) byłoby bardziej pożądane uzyskanie „aAàbBcCdDeé”.
eljenso
1
@YiweiG W tym przypadku odpowiedź brzmi: zdecydowanie nie. sortedjest już String… czego można by się spodziewać, toString()gdy go wezwiesz?
Jon Skeet
1
@Hengameh: Sortujesz tablicę znaków, ale potem ją ignorujesz. Chciałbyśchar[] c = s.toCharArray(); Arrays.sort(c); String sorted = new String(c);
Jon Skeet
49

Nie, nie ma wbudowanej metody String. Możesz przekonwertować go na tablicę znaków, posortować za pomocą Arrays.sort i przekonwertować z powrotem na String.

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

Lub, jeśli chcesz poprawnie radzić sobie z rzeczami specyficznymi dla języka, takimi jak wielkie litery i znaki akcentowane:

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
źródło
FYI: ta metoda podzieli 32-bitowe punkty kodowe na dwa znaki Unicode o wartości większej niż 0xFFFF, tworząc łańcuchy z nieprawidłowymi wartościami. Nie dotyczy języka francuskiego, ale może powodować problemy w niektórych lokalizacjach.
McDowell
Zobacz Character.isHighSurrogate (char)
McDowell
2
Jakoś myślę, że to wystarczy ... chyba że chce posortować ciągi
znaków
3
"Myślę, że to wystarczy ... chyba że chce posortować ciągi znaków zawierające suahili" - widzę slogan - Unicode: gdy chcesz mieć łatwy sposób na lokalizację i tłumaczenie aplikacji na niektóre języki. Bzzt. Zawieść. Postępowanie prawie dobrze oznacza, że prawie nie masz błędu do naprawienia później.
Jonas Kölker
1
@Jonas Powiedziałem, że myślę , chyba że PO chce sprecyzować, że wsparcie suahili jest absolutnie konieczne. Wolę nawet proste rozwiązanie bez lokalizacji, chyba że OP stwierdza, że ​​to nie jest wystarczające. Słyszałeś kiedyś o zasadzie YAGNI?
eljenso
34

W Javie 8 można to zrobić za pomocą:

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

Nieco krótsza alternatywa, która działa ze strumieniem ciągów o długości jeden (każdy znak w nieposortowanym łańcuchu jest konwertowany na ciąg w strumieniu):

String sorted =
    Stream.of("edcba".split(""))
        .sorted()
        .collect(Collectors.joining());
Marcin
źródło
@Dennis na którym dokładnie i dlaczego?
Marcin
Pierwszy bit, w którym próbujesz posortować String. Wygląda dobrze, ale kiedy porównałem go z dużym zestawem danych, było trochę wolniej w porównaniu z odpowiedzią Jona Skeetsa.
Dennis
18

Konwertuj na tablicę znakówSortujKonwertuj z powrotem na łańcuch :

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
źródło
Co było punktem na dodaniu tej odpowiedzi 4 lata po inni napisali co najmniej 3 identyczne odpowiedzi
Nick Cardoso
1
@NickCardoso Naprawdę nie pamiętam, pytasz mnie o odpowiedź, którą zamieściłem na moich bardzo wczesnych etapach na Stack Overflow. Czy naprawdę czekasz na wyjaśnienie w tej sprawie?
Maroun
@NickCardoso W ogóle nie próbuję ci usprawiedliwiać. Twój komentarz i głos przeciwny na razie niczego nie zmieni. Tak postanowiłem CZTERY lata temu, nie rozumiem, po co teraz o tym
wspominać
17

Bardziej surowe podejście bez użycia metody sortowania Arrays.sort. To jest sortowanie przez wstawianie.

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);
}
agaase
źródło
1
pytanie zadawane w sposób natywny w javie, bez użycia innego algorytmu sortowania.
Vikrant Goel
1
Zagłosowano, ponieważ było to przydatne rozwiązanie, a nie dlatego, że była to żądana odpowiedź.
Chris
1
@VikrantGoel "Native way in Java" - co nie jest natywne w tym podejściu? nie widzę żadnych wymagań innych firm. Czy ty?
Nick Cardoso
To powinna być prawidłowa odpowiedź. Jak powiedział @NickCardoso ... nic nie jest bardziej "natywne w javie" niż to.
Mariano Zorrilla
14
    String a ="dgfa";
    char [] c = a.toCharArray();
    Arrays.sort(c);
    return new String(c);

Zauważ, że nie zadziała to zgodnie z oczekiwaniami, jeśli będzie to mieszana wielkość liter String (wielkie litery zostaną umieszczone przed małymi). Możesz przekazać komparator do metody Sort, aby to zmienić.

dobrze
źródło
1
musisz importować java.util.Arrays; bo inaczej to nie zadziała
hopper
3

Procedura:

  1. Najpierw przekonwertuj ciąg na tablicę znaków
  2. Następnie posortuj tablicę znaków
  3. Przekonwertuj tablicę znaków na ciąg
  4. Wydrukuj ciąg

Fragment kodu:

    String input = "world";
    char[] arr = input.toCharArray();
    Arrays.sort(arr);
    String sorted = new String(arr);
    System.out.println(sorted);
zrazy
źródło
Czy to żart? Zamieszczasz identyczne odpowiedzi na pytanie mające 8 lat? Jak leniwy.
Nick Cardoso
Jestem ignorantem. Wybacz mi.
rashedcs
2

Pytanie: sortuj ciąg w 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
źródło
-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
źródło
-2

Bez używania kolekcji w Javie:

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

Wynik:

wprowadź ciąg ==

sortowanie

po sortowaniu == ginorst

naveen prasanna
źródło
Powinieneś ponownie spojrzeć na> =. Co się dzieje z „mnmnmnm” jako ciągiem?
Nick Cardoso