Почему мой цикл сортировки, кажется, добавляет элемент там, где он не должен?


Я пытаюсь отсортировать массив строк с помощью 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 68

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

}