Почему мой цикл сортировки, кажется, добавляет элемент там, где он не должен?
Я пытаюсь отсортировать массив строк с помощью compareTo()
. Это мой код:
static String Array[] = {" Hello ", " This ", "is ", "Sorting ", "Example"};
String temp;
public static void main(String[] args)
{
for (int j=0; j<Array.length;j++)
{
for (int i=j+1 ; i<Array.length; i++)
{
if (Array[i].compareTo(Array[j])<0)
{
String temp = Array[j];
Array[j] = Array[i];
Array[i] = temp;
}
}
System.out.print(Array[j]);
}
}
теперь выход:
Hello This Example Sorting is
Я получаю результаты, но не те результаты, которые я хочу получить, которые являются:
Hello This Example Is Sorting
как я могу настроить свой код для правильной сортировки массива строк?
8 ответов:
ваш вывод правильный. Обозначьте белые символы "привет" и " это " в начале.
еще одна проблема связана с вашей методологией. Используйте
Arrays.sort()
способ:String[] strings = { " Hello ", " This ", "Is ", "Sorting ", "Example" }; Arrays.sort(strings);
выход:
Hello This Example Is Sorting
здесь третий элемент массива " is "должен быть" Is", иначе он придет последним после сортировки. Поскольку метод сортировки внутренне использует значение ASCII для сортировки элементов.
кроме альтернативных решений, которые были размещены здесь (которые являются правильными), никто на самом деле не ответил на ваш вопрос, обратившись к тому, что было не так с вашим кодом.
похоже, что вы пытались реализовать сортировка выбор. Я не буду вдаваться в подробности того, как сортировка работает здесь, но я включил несколько ссылок для вашей ссылки =)
ваш код был синтаксически верные, но логически неправильным. Вы были частично сортировка строк только сравнивая каждую строку со строками, которые пришли после. Вот исправленная версия (я сохранил столько же вашего исходного кода, чтобы проиллюстрировать, что было" неправильно " с ним):
static String Array[]={" Hello " , " This " , "is ", "Sorting ", "Example"}; String temp; //Keeps track of the smallest string's index int shortestStringIndex; public static void main(String[] args) { //I reduced the upper bound from Array.length to (Array.length - 1) for(int j=0; j < Array.length - 1;j++) { shortestStringIndex = j; for (int i=j+1 ; i<Array.length; i++) { //We keep track of the index to the smallest string if(Array[i].trim().compareTo(Array[shortestStringIndex].trim())<0) { shortestStringIndex = i; } } //We only swap with the smallest string if(shortestStringIndex != j) { String temp = Array[j]; Array[j] = Array[shortestStringIndex]; Array[shortestStringIndex] = temp; } } }
Более Дальнеишее Чтение
проблема с этим подходом заключается в том, что его асимптотическая сложность O (n^2). Проще говоря, он становится очень медленным, поскольку размер массива растет (приближается к бесконечности). Вы можете прочитать о лучшие способы сортировки данных, например quicksort.
вместо этой строки
if(Array[i].compareTo(Array[j])<0)
использовать эту строку
if(Array[i].trim().compareTo(Array[j].trim())<0)
и вы хорошо идти. Почему ваш текущий код не работает уже объяснили другие пользователи. Это выше замена является одним обходным путем среди нескольких, которые вы могли бы применить.
Я знаю, что это поздний ответ, но, возможно, он может помочь кому-то.
удаление пробелов можно выполнить с помощью функции trim (). После этого, если вы хотите отсортировать массив с учетом регистра, вы можете просто использовать:
Arrays.sort(yourArray);
и для случая нечувствительным образом:
Arrays.sort(yourArray,String.CASE_INSENSITIVE_ORDER);
надеюсь, что это помогает!
начиная от Java 8, вы также можете использовать
parallelSort
что полезно, если у вас есть массивы, содержащие много элементов.пример:
public static void main(String[] args) { String[] strings = { "x", "a", "c", "b", "y" }; Arrays.parallelSort(strings); System.out.println(Arrays.toString(strings)); // [a, b, c, x, y] }
если вы хотите игнорировать делу, вы можете использовать:
public static void main(String[] args) { String[] strings = { "x", "a", "c", "B", "y" }; Arrays.parallelSort(strings, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.compareToIgnoreCase(o2); } }); System.out.println(Arrays.toString(strings)); // [a, B, c, x, y] }
иначе
B
будет передa
.если вы хотите игнорировать конечные пробелы во время сравнения, вы можете использовать
trim()
:public static void main(String[] args) { String[] strings = { "x", " a", "c ", " b", "y" }; Arrays.parallelSort(strings, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.trim().compareTo(o2.trim()); } }); System.out.println(Arrays.toString(strings)); // [ a, b, c , x, y] }
посмотреть:
" Hello " , " This " , "is ", "Sorting ", "Example"
прежде всего вы предоставили пробелы в
" Hello "
и" This "
, пробелы имеют меньшее значение, чем буквенные символы в Юникоде, поэтому он печатается первым. (Остальные символы были отсортированы в алфавитном порядке).теперь заглавные буквы имеют меньшее значение, чем строчная буква в Юникоде, поэтому" пример "и" сортировка " печатаются, а затем, наконец,
"is "
который имеет самое высокое значение.
Если вы используете:
if (Array[i].compareToIgnoreCase(Array[j]) < 0)
вы получите:
Example Hello is Sorting This
который я думаю, что это выход, который вы искали.
начнем с того, что ваша проблема заключается в том, что вы используете метод `compareTo (), который чувствителен к регистру. Это означает, что заглавные буквы сортируются отдельно от нижних. Причина в том, что он переведен в Unicode, где заглавные буквы представлены цифрами, которые меньше, чем представленное число нижнего регистра. Таким образом, вы должны использовать `compareToIgnoreCase () как многие уже упоминалось в предыдущих постах.
это мой полный пример подхода, как вы можете это сделать эффективно
после создания объекта компаратор вы можете передать его в этой версии ' sort ()', которая определена в java.утиль.Массивы.
static<T>void sort(T[]array,Comparator<?super T>comp)
внимательно посмотри супер. это гарантирует, что массив, который передается в совместим с типом компаратора.
волшебная часть этого способа заключается в том, что вы можете легко сортировать массив строк в обратный порядок вы можете легко сделать с помощью:
return strB.compareToIgnoreCase(strA);
import java.util.Comparator; public class IgnoreCaseComp implements Comparator<String> { @Override public int compare(String strA, String strB) { return strA.compareToIgnoreCase(strB); } }
import java.util.Arrays; public class IgnoreCaseSort { public static void main(String[] args) { String strs[] = {" Hello ", " This ", "is ", "Sorting ", "Example"}; System.out.print("Initial order: "); for (String s : strs) { System.out.print(s + " "); } System.out.println("\n"); IgnoreCaseComp icc = new IgnoreCaseComp(); Arrays.sort(strs, icc); System.out.print("Case-insesitive sorted order: "); for (String s : strs) { System.out.print(s + " "); } System.out.println("\n"); Arrays.sort(strs); System.out.print("Default, case-sensitive sorted order: "); for (String s : strs) { System.out.print(s + " "); } System.out.println("\n"); } }
run: Initial order: Hello This is Sorting Example Case-insesitive sorted order: Hello This Example is Sorting Default, case-sensitive sorted order: Hello This Example Sorting is BUILD SUCCESSFUL (total time: 0 seconds)
Альтернативный Вариант
метод
compareToIgnoreCase()
, хотя он хорошо работает со многими случаями(так же, как сравнить строку на английском языке), он не будет хорошо работать со всеми языки и места. Это автоматически делает его непригодным для использования. Чтобы убедиться, что он будет поддерживаться везде, вы должны использоватьcompare()
от java.текст.Подборочная машина.вы можете найти коллатор для вашего местоположения, вызвав метод
getInstance()
. После этого вы должны установить свойство силы этого Коллатора. Это можно сделать с помощьюsetStrength()
метод вместе сCollator.PRIMARY
в качестве параметра. С этой альтернативой выберите IgnocaseComp может быть написано так же, как ниже. Эта версия кода будет генерировать один и тот же вывод независимо от расположениеimport java.text.Collator; import java.util.Comparator; //this comparator uses one Collator to determine //the right sort usage with no sensitive type //of the 2 given strings public class IgnoreCaseComp implements Comparator<String> { Collator col; IgnoreCaseComp() { //default locale col = Collator.getInstance(); //this will consider only PRIMARY difference ("a" vs "b") col.setStrength(Collator.PRIMARY); } @Override public int compare(String strA, String strB) { return col.compare(strA, strB); } }