0

我需要按字母顺序组织一个字符串数组。理论上,每个单词的第一个字母都是大写的(虽然不一定,因为不能总是信任用户)。我试过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。它现在可以工作,但输出如下: Joe
Bill
Bob
Smith
Rodney
James
Philip
Lillian
Charlie
Angel
Carol
Noah
我现在添加了整个代码部分(当然,减去了 while 循环)。这基本上是我找到的确切解决方案,也是第一个给我任何输出的解决方案。我究竟做错了什么?

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

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

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

4

5 回答 5

1

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

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

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

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;
    }
  }
}
于 2013-09-08T23:33:22.073 回答
1

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

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());
        }
于 2018-05-07T05:40:53.677 回答
0

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

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

  1. 通过创建一个新的(较小的)数组来消除null这些值,并消除空值。

  2. 将这些值替换为可以安全比较而不会导致 NPEnull的某个值(例如空)。String

  3. 实现Comparator可以容忍nulls 的 a。例如,如果我们想对null非空字符串进行排序......

      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数组中有 a ,则 之前的任何非空元素null都不能与 . 之后的任何非空元素进行比较null

于 2013-09-09T02:31:34.710 回答
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
}
于 2018-09-15T18:31:43.413 回答
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 是可变的,因此您的手动排序算法应该适用于它们。

希望这可以帮助。

于 2018-05-16T14:26:12.443 回答