如何按字母顺序排序String数组(不使用compareTo或Arrays.sort)
我需要按字母顺序组织一个字符串数组。 从理论上讲,每个单词的第一个字母都是大写的(尽管不一定,因为人们不能总是信任用户)。 我试过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;i0) { 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);
排序本身的代码基本上就是下面的答案。
假设您正在运行冒泡排序算法的某些变体,并且您尚未清理输入数组的空字符串,则问题很可能是organizedNames[i]
为空。
如果是这种情况,您需要决定是否要删除空项,或者在数组末尾列出它们。 如果后者为真,则在进行比较之前,检查name1 == null || name2 == null
name1 == null || name2 == null
如果是这样,将num设置为-1,这会将所有null项放在一个数组中。
要回答您的次要问题,请尝试以下方法:
boolean done = false; while(done == false){ done = true; for(int i=0;i0) { String temp=organizedNames[i]; organizedNames[i]=organizedNames[i+1]; organizedNames[i+1]=temp; done=false; } } }
你已经把自己搞得一团糟了! 你一直在尝试做的是从头开始实现你自己的排序算法,而不理解为什么原始版本不起作用。 它没有用……出于同样的原因原始版本不起作用。
如果我正确读取证据,则问题的根本原因是输入数组中的null
值。 有三种简单的方法可以解决这个问题:
-
通过创建一个消除了
null
值的新(较小)数组来摆脱null
值。 -
将
null
值替换为可以安全地比较而不会导致NPE的某个值(例如,空String
)。 -
实现一个容忍
null
的Comparator
。 例如,如果我们想在非空字符串之后进行null
排序…public class MyComparator implements Comparator
{ 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之前的任何非null元素都不能与null之后的任何非null元素进行比较。
使用集合我们可以这样做..
SortedSet set = new TreeSet (); 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()); }
首先,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是可变的,因此您的手动排序算法应该适用于它们。
希望这可以帮助。
使用此代码不使用任何预定义的 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 }