为什么我的排序循环似乎将元素添加在不应添加的位置?


71

我正在尝试使用排序字符串数组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

如何调整代码以正确地对字符串数组进行排序?


7
您应该真正按照自己的代码约定进行工作。

是的,我会感染java的新手。并完全坚持下去,对这些小问题一无所知..
Sikander 2012年

2
当编程与约定保持一致时,我可以给您一些建议。如果您在某件事上错了,那就在任何地方都做错一件事,而不是在某些地方做错了,而在其他地方做错了。

Answers:


146

您的输出是正确的。开头用白色字符表示“ Hello”和“ This”。

另一个问题与您的方法有关。使用Arrays.sort()方法:

String[] strings = { " Hello ", " This ", "Is ", "Sorting ", "Example" };
Arrays.sort(strings);

输出:

 Hello
 This
Example
Is
Sorting

这里数组“ is”的第三个元素应该是“ Is”,否则它将在排序后排在最后。因为sort方法在内部使用ASCII值对元素进行排序。


如果我有两个领域的课程怎么办:1)text2)code。然后我创建了arraylist。我想对arraylist元素进行排序text
亚历克斯(Alex)

2
@Alex请阅读有关在Java中实现Comparable接口的信息。
Juvanis '16

15

除了此处发布的替代解决方案(是正确的)之外,没有人通过解决您的代码有什么问题来实际回答您的问题。

似乎您正在尝试实现选择排序算法。在这里,我不会详细介绍排序的方式,但是我提供了一些链接供您参考=)

您的代码在语法上是正确的,但在逻辑上是错误的。您仅通过将每个字符串与它后面的字符串进行比较来对字符串进行部分排序。这是一个更正的版本(我保留了您的大部分原始代码,以说明其中的“错误”):

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


10

我知道这是一个晚答复,但也许可以帮助某人。

可以通过使用trim()函数来删除空格。之后,如果您要使用区分大小写的方式对数组进行排序,则可以使用:

Arrays.sort(yourArray);

对于不区分大小写的方式:

Arrays.sort(yourArray,String.CASE_INSENSITIVE_ORDER);

希望这可以帮助!


9

代替这条线

if(Array[i].compareTo(Array[j])<0)

用这条线

if(Array[i].trim().compareTo(Array[j].trim())<0)

而且你很好。您的当前代码不起作用的原因已经由其他用户解释。上面的替换是您可以应用的几种替代方法之一。


5

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]
}


4

" Hello " , " This " , "is ", "Sorting ", "Example"

首先,您在" Hello "和中提供了空格" This ",空格的值比Unicode中的字母字符小,因此要先打印。(其余字符按字母顺序排序)。

现在,大写字母的值比Unicode中的小写字母的值低,因此将打印“ Example”和“ Sorting”,最后"is "是最高值。


4

如果您使用:

if (Array[i].compareToIgnoreCase(Array[j]) < 0)

你会得到:

Example  Hello  is  Sorting  This

我认为这是您想要的输出。


我认为这是您要查找的输出-并非根据昨天发生的编辑。
BSMP

2

首先,您的问题是使用区分大小写的方法`compareTo()。这意味着大写字母与小写字母分开排列。原因是它翻译成Unicode,其中大写字母的数字小于小写字母的数字。因此,您应该使用“ compareToIgnoreCase()”,就像以前的文章中提到的一样。

这是我如何有效执行操作的完整示例方法

创建比较器的对象后,您可以在java.util.Arrays中定义的此sort()版本中传递它。

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.text.Collat​​or中使用。

您可以通过调用方法找到适合您所在位置的整理器getInstance()。之后,您应该设置此整理器的强度属性。可以使用setStrength()方法和Collator.PRIMARYas参数来完成此操作。通过这种选择,可以像下面这样编写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);
    }

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.