Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 字符串基数排序-StringIndexOutOfBoundsEception_Java_String_Sorting_Substring_Radix Sort - Fatal编程技术网

Java 字符串基数排序-StringIndexOutOfBoundsEception

Java 字符串基数排序-StringIndexOutOfBoundsEception,java,string,sorting,substring,radix-sort,Java,String,Sorting,Substring,Radix Sort,我正在编写我自己的基数排序方法来对字符串中的单词进行排序(大黑猫坐在 漂亮的棕色垫将被分类为座椅上漂亮的大黑棕色猫垫)。该方法接收单个单词的列表(我自己的列表界面),并将列表重新排序 以下是我目前的方法: public static void stringRadixSort(List<String> list, int letters) { List<String>[] buckets = (List<String>[]) Array.newInsta

我正在编写我自己的基数排序方法来对字符串中的单词进行排序(
大黑猫坐在
漂亮的棕色垫
将被分类为座椅上漂亮的大黑棕色猫垫)。该方法接收单个单词的列表(我自己的列表界面),并将列表重新排序

以下是我目前的方法:

public static void stringRadixSort(List<String> list, int letters) {
    List<String>[] buckets = (List<String>[]) Array.newInstance(List.class, 26);

    int letterNumber = 1; //Sorts list by 1st letter of each word, then 2nd etc.
    for (int i = 0; i < letters; i++) {
        while (!list.isEmpty()) {
            String word = list.remove(list.first());
            if (word.length() > letters) throw new UnsortableException("The list contains a word that holds more letters than the given maximum number of letters."
                    + "\nMax Letters: " + letters + "\nWord: " + word);
            String letter = word.substring(letterNumber - 1, letterNumber); //EXCEPTION THROWN
            char ch = letter.charAt(0);
            int index = ch - 'a';    //gets index of each letter ('a' = buckets[0], 'z' = buckets[25]
            if (buckets[index] == null) {
                buckets[index] = new LinkedList<String>();
            }
            buckets[index].insertLast(word);
        }

        for (int j = 0; j < buckets.length; j++) {
            if (buckets[j] != null) {
                while (!buckets[j].isEmpty()) {
                    list.insertLast(buckets[j].remove(buckets[j].first()));
                }
            }
        }
        letterNumber++;
    }
}
publicstaticvoidstringradixsort(列表,整数字母){
List[]bucket=(List[])Array.newInstance(List.class,26);
int letterNumber=1;//按每个单词的第一个字母对列表排序,然后按第二个字母排序,以此类推。
for(int i=0;iletters)抛出新的不可排序异常(“列表中包含的单词包含的字母数超过了给定的最大字母数。”
+“\n最大字母:“+字母+”\n单词:“+单词”;
String letter=word.substring(letterNumber-1,letterNumber);//引发异常
char ch=字母charAt(0);
int index=ch-'a';//获取每个字母的索引('a'=bucket[0],'z'=bucket[25]
if(bucket[索引]==null){
bucket[index]=新的LinkedList();
}
bucket[index].insertLast(word);
}
对于(int j=0;j
我希望我的方法(唯一)的问题是,当我阅读单词的每个字符时,我会创建单词的单个字母子字符串。因为外部
for
循环通过
letters
次(其中
letters
是列表中单词的最大长度),当此循环的迭代长度大于当前单词的长度时,即
letterNumber>word.length()
,将引发异常,因此它试图使用大于字符串长度的字符串索引创建子字符串

我如何调整我的方法,使其只创建每个单词的子字符串,直到
letterNumber==word.length()
,然后还能将排序算法应用于这些较短的单词——“a”将变为“aa”之前的单词。

为什么不替换

String letter = word.substring(letterNumber - 1, letterNumber);
char ch = letter.charAt(0);

这将直接为您提供
char
。但这并不能解决
IndexOutOfBoundException
的问题

当然,您应该捕获异常并处理它。在这种情况下,创建一个bucket可能会更好:当单词对于当前迭代来说太短时,它会被排序到一个bucket中。当将列表重新合并在一起时,首先获取该bucket的元素

public static void stringRadixSort(List<String> list, int letters) {
    List<String>[] buckets = (List<String>[]) Array.newInstance(List.class, 27);

    int letterNumber = 1; //Sorts list by 1st letter of each word, then 2nd etc.
    for (int i = 0; i < letters; i++) {
        while (!list.isEmpty()) {
            String word = list.remove(list.first());
            if (word.length() > letters) throw new UnsortableException("The list contains a word that holds more letters than the given maximum number of letters."
                + "\nMax Letters: " + letters + "\nWord: " + word);
            int index;
            if(word.length() > letterNumber) {
                char ch = word.charAt(letterNumber - 1);
                index = ch - 'a' + 1;    //gets index of each letter ('a' = buckets[1], 'z' = buckets[26], buckets[0] is for short words
            } else {
                index = 0;
            }
            if (buckets[index] == null) {
                buckets[index] = new LinkedList<String>();
            }
            buckets[index].insertLast(word);
        }

        for (int j = 0; j < buckets.length; j++) {
            if (buckets[j] != null) {
                while (!buckets[j].isEmpty()) {
                    list.insertLast(buckets[j].remove(buckets[j].first()));
                }
            }
        }
        letterNumber++;
    }
}
publicstaticvoidstringradixsort(列表,整数字母){
List[]bucket=(List[])Array.newInstance(List.class,27);
int letterNumber=1;//按每个单词的第一个字母对列表排序,然后按第二个字母排序,以此类推。
for(int i=0;iletters)抛出新的不可排序异常(“列表中包含的单词包含的字母数超过了给定的最大字母数。”
+“\n最大字母:“+字母+”\n单词:“+单词”;
整数指数;
if(word.length()>letterNumber){
char ch=单词charAt(字母编号-1);
index=ch-'a'+1;//获取每个字母的索引('a'=buckets[1],'z'=buckets[26],buckets[0]表示短单词
}否则{
指数=0;
}
if(bucket[索引]==null){
bucket[index]=新的LinkedList();
}
bucket[index].insertLast(word);
}
对于(int j=0;j
只需将短于字符串长度的元素分组到另一个组中。您还需要首先对最低有效(相关)字符进行排序。以下代码使用java集合,而不是您使用的任何数据结构:

public static void stringRadixSort(List<String> list, int letters) {
    if (list.size() <= 1) {
        return;
    }

    List<String>[] buckets = new List[27];
    for (int i = 0; i < buckets.length; i++) {
        buckets[i] = new LinkedList<>();
    }
    int largestLength = -1;
    int secondLargestLength = 0;
    for (String s : list) {
        int length = s.length();
        if (length >= largestLength) {
            secondLargestLength = largestLength;
            largestLength = length;
        } else if (secondLargestLength < length) {
            secondLargestLength = length;
        }
    }

    if (largestLength > letters) {
        throw new IllegalArgumentException("one of the strings is too long");
    }

    for (int i = secondLargestLength == largestLength ? secondLargestLength-1 : secondLargestLength; i >= 0; i--) {
        for (String word : list) {
            int index = (word.length() <= i) ? 0 : word.charAt(i) - ('a' - 1);
            buckets[index].add(word);
        }

        list.clear();

        for (List<String> lst : buckets) {
            if (lst != null) {
                list.addAll(lst);
                lst.clear();
            }
        }
    }
}
publicstaticvoidstringradixsort(列表,整数字母){
if(list.size()=最大长度){
第二大长度=最大长度;
最大长度=长度;
}else if(第二大长度<长度){
第二大长度=长度;
}
}
如果(最大长度>字母){
抛出新的IllegalArgumentException(“其中一个字符串太长”);
}
对于(int i=secondLargestLength==largestLength?secondLargestLength-1:secondLargestLength;i>=0;i--){
for(字符串字:列表){

int index=(word.length()在我所有的尝试中,我都是先按最高有效字母(每个单词的第一个字母)对单词进行排序,然后按下一个有效字母进行排序,依此类推。当然,基数排序依赖于对最低有效数字/字母(数字/单词的最后一个数字/字母)进行排序.因此,我不是从
letterNumber=1
开始,在每次迭代后递增,而是从
letterNumber=maxWordLength
开始,然后在每次迭代后递减,以便每次迭代都比较下一个最重要的字母

@SuppressWarnings("unchecked")
public static void stringRadixSort(List<String> list) {
    List<String>[] buckets = (List<String>[]) Array.newInstance(List.class, 27);

    //Find longest word in list
    int maxWordLength = 0;
    for (String word : list) {
        if (word.length() > maxWordLength) {
            maxWordLength = word.length();
        }
    }

    //Sorts list based on least significant letter (last letter of word) to most significant
    int letterNumber = maxWordLength;
    for (int i = 0; i < maxWordLength; i++) {
        while (!list.isEmpty()) {
            String word = list.remove(list.first());
            int index = 0;
            if(word.length() >= letterNumber) {
                char ch = word.charAt(letterNumber - 1);
                index = ch - 'a' + 1;    //gets index of each letter ('a' = buckets[1], 'z' = buckets[26], buckets[0] is for words shorter than 'letterNumber')
            }
            if (buckets[index] == null) {
                buckets[index] = new LinkedList<String>();
            }
            buckets[index].insertLast(word);
        }

        for (int j = 0; j < buckets.length; j++) {
            if (buckets[j] != null) {
                while (!buckets[j].isEmpty()) {
                    list.insertLast(buckets[j].remove(buckets[j].first()));
                }
            }
        }
        letterNumber--;
    }
}
@SuppressWarnings(“未选中”)
公共静态无效stringRadixSort(列表){
List[]bucket=(List[])Array.newInstance(List.class,27);
//查找列表中最长的单词
int maxWordLength=0;
@SuppressWarnings("unchecked")
public static void stringRadixSort(List<String> list) {
    List<String>[] buckets = (List<String>[]) Array.newInstance(List.class, 27);

    //Find longest word in list
    int maxWordLength = 0;
    for (String word : list) {
        if (word.length() > maxWordLength) {
            maxWordLength = word.length();
        }
    }

    //Sorts list based on least significant letter (last letter of word) to most significant
    int letterNumber = maxWordLength;
    for (int i = 0; i < maxWordLength; i++) {
        while (!list.isEmpty()) {
            String word = list.remove(list.first());
            int index = 0;
            if(word.length() >= letterNumber) {
                char ch = word.charAt(letterNumber - 1);
                index = ch - 'a' + 1;    //gets index of each letter ('a' = buckets[1], 'z' = buckets[26], buckets[0] is for words shorter than 'letterNumber')
            }
            if (buckets[index] == null) {
                buckets[index] = new LinkedList<String>();
            }
            buckets[index].insertLast(word);
        }

        for (int j = 0; j < buckets.length; j++) {
            if (buckets[j] != null) {
                while (!buckets[j].isEmpty()) {
                    list.insertLast(buckets[j].remove(buckets[j].first()));
                }
            }
        }
        letterNumber--;
    }
}