如何按字母顺序排序String数组(不使用compareTo或Arrays.sort)

时间:2013-09-08 23:27:14

标签: java arrays sorting

我需要按字母顺序组织一个字符串数组。从理论上讲,每个单词的第一个字母都是大写的(尽管不一定,因为人们不能总是信任用户)。我试过了Arrays.sort(),它不会运行程序。我尝试过使用compareTo(),当它运行程序时,当它到达该部分代码时,我收到此错误:

Exception in thread "main" java.lang.NullPointerException
        at java.lang.String.compareTo(Unknown Source)
    at NameandAge.printNameOrder(NameandAge.java:431)
    at NameandAge.print(NameandAge.java:350)
    at NameandAge.main(NameandAge.java:116)

从字面上看,我在这个问题上能找到的一切都给了我这两种解决方案中的一种。还有其他建议吗?

(对于记录,代码当前为:)

while(!done)
{
    done=true;   
    for(int i=0;i<organizedNames.length-1;i++)
    {
        if(!(organizednames[i]==null))
        {
            String name1=organizedNames[i]; String name2=organizedNames[i+1];
            if(name1!=null&&name2!=null)
            {
                int num=name1.compareTo(name2);
                if(num>0)
                { 
                    temp=organizedNames[i]; //temp is a String that was declared earlier
                    organizedNames[i]=organizedNames[i+1];
                    organizedNames[i+1]=temp;
                    done=false 
                }
            }
        }
    }
}

编辑:尝试检查以确保name1和name2不是null。它现在有效,但这是输出:      乔
     比尔
     鲍勃
     史密斯
     罗德尼
     詹姆斯
     菲利普
     莉莲
     查理
     天使
     卡罗尔
     诺亚
我现在添加了整段代码(当然,减去while循环)。这基本上是我找到的确切解决方案,也是第一个给我任何输出的解决方案。我究竟做错了什么?

编辑(再次):这是调用排序的代码。

String[]organizedNames=new String[names.length];
organizedNames=sortNames(organizedNames);

排序的代码本身基本上就是下面的答案。

5 个答案:

答案 0 :(得分:1)

假设您正在运行冒泡排序算法的某些变体,并且您尚未清理输入数组的空字符串,则问题可能是organizedNames[i]为空。

如果是这种情况,您需要决定是否要删除空项,或者在数组末尾列出它们。如果后者为真,那么在进行比较之前,检查是否name1 == null || name2 == null如果是,将num设置为-1,这将把所有空项放在一个数组中。

要回答您的第二个问题,请尝试以下操作:

boolean done = false;
while(done == false){
  done = true;
  for(int i=0;i<organizedNames.length-1;i++)
  {
    int num = 0;
    if(organizedNames[i] != null && organizedNames[i + 1] != null)
    {
        String name1=organizedNames[i]; String name2=organizedNames[i+1];
        num=name1.compareTo(name2);
    }
    else if(organizedNames[i] == null && organizedNames[i + 1] == null){
      num = 0;
    }
    else if(organizedNames[i] == null){
      num = 1;
    }
    else {
      num = -1;
    }
    if(num>0)
    {
        String temp=organizedNames[i];
        organizedNames[i]=organizedNames[i+1];
        organizedNames[i+1]=temp;
        done=false;
    }
  }
}

答案 1 :(得分:0)

你已经把自己搞得一团糟了!你一直在尝试做的是从头开始实现你自己的排序算法,而不理解为什么原始版本不起作用。它不起作用......出于同样的原因,原始版本不起作用。

如果我正确阅读证据,则问题的根本原因是输入数组中的null值。有三种简单的方法可以解决这个问题:

  1. 通过创建一个消除了空值的新(较小)数组来摆脱null值。

  2. null值替换为某些值(例如空String),可以安全地比较而不会导致NPE。

  3. 实施一个容忍Comparator的{​​{1}}。例如,如果我们想在非空字符串后对null进行排序......

    null
  4. 如果您对问题中的代码未正确排序感兴趣,那是因为您处理 public class MyComparator implements Comparator<String> { public int compare(String s1, String s2) { if (s1 == null) { return (s2 == null) ? 0 : +1; } else { return (s2 == null) ? -1 : s1.compareTo(s2); } } } String[] array = ... Arrays.sort(array, new MyComparator()); 的策略。基本上,代码(如编写的)比较连续的数组条目对,如果它们乱序则交换它们。当它通过没有找到任何东西的数组进行交换时,它就会停止。问题是如果它所比较的​​任何一个元素是null,它就不会比较它们。因此,如果数组中有null,则null之前的任何非空元素都无法与null之后的任何非空元素进行比较。

答案 2 :(得分:0)

使用集合我们可以这样做..

SortedSet<String> set = new TreeSet<String>();
String[] s = { "this", "will", "be", "sorted", "without", "ba", "any", "sort()", "function", "or","comparator" };

        for (int i = 0; i < s.length; i++)
        {
            set.add(s[i]);
        }

        for (Object element : set) {
            System.out.println(element.toString());
        }

答案 3 :(得分:0)

首先,String类是不可变的,即无论你如何排序或排列它。它永远不会改变自身内部的插入顺序。

这样做的原因是,当您创建String类对象时,将在String Constant / Literal Pool中分配一个内存,该内存可能被同时在同一JRE上运行的许多其他程序/方法使用。

 class Test{  
 public static void main(String args[]){  
   String s="Jake";  
   s.concat(" Paul");//concat() method appends the string at the end  
   System.out.println(s);//will print Jake because strings are immutable objects  
 }  
}  

因此,尝试通常的排序算法不会在这里工作。

您可以使用StringBuilder而不是String。由于StringBuilder是可变的,因此您的手动排序算法应该适用于它们。

希望这会有所帮助。

答案 4 :(得分:0)

使用此代码,该代码不使用任何预定义的 Array.Sort()compareTo() 方法

sortStringArray(new String[]{"Henry Bernard",
            "Cherish Davidson",
            "Joshua Norris",
            "Eleanor Kelley",
            "Jaslyn Schneider",
            "Holly Herman",
            "Willie Strong",
            "Eliana Villa",
            "Lennon Odom",
            "Monica Velasquez",
            "Salvatore Levy",
            "Taliyah Bruce"});

public static void sortStringArray(String[] array) {
    for (int i = 0; i <= array.length - 1; i++) {
        for (int j = 1; j < array.length - i; j++) { //Apply the bubble Sort
            if (CompareString(array[j - 1], array[j]) == 1) { //Pass the two adjacent string for comparing
                String temp = array[j - 1];
                array[j - 1] = array[j];
                array[j] = temp;
            }
        }
    }

    for (int i = 0; i <= array.length - 1; i++) {
        System.out.println(array[i]);
    }
}

private static int CompareString(String first, String second) {
    int len;

    if (first.length() >= second.length()) //we need to take the smallest string length
        len = second.length();
    else
        len = first.length();

    for (int i = 0; i <= len; i++) {
        if (first.charAt(i) > second.charAt(i))  //Suppose the first string letters is greater then return 1; 
            return 1;
        else if (first.charAt(i) < second.charAt(i)) //if second string letter is greater then return -1;
            return -1;
    }
    return 0;  //if both the equal then return 0
}