【问题标题】:How can I optimize this "sort"?如何优化这种“排序”?
【发布时间】:2020-06-15 05:37:04
【问题描述】:

所以我正在编写一个算法,它接收一个排序字符串数组,并用字符串填充一个单独用户定义的链表数组。每个链表都是一个字谜列表。例如,一个列表可能包含“car”和“arc”,因为它们都包含字母 a、c 和 r。

数组的每个标题必须按原始列表的字母顺序排列。所以基本上,如果我有输入 {"arc", "bed", "car", "deb", "xylophone"},我会得到输出:

圆弧,汽车

床,deb

木琴

我如何实现这一点是通过使用嵌套的 for 循环。外循环采用第 i 个元素,或列表的“键”,内循环采用链表数组的第 j 个元素。如果第 j 个列表的标题为空,则立即将键放入 j 并中断。如果标头不包含 null 并且键是标头的字谜,则将其添加到列表中。我的链表自动排序。

现在这对于小输入非常有效。但是对于非常大的输入,例如 n = 15000,完成嵌套循环需要 2 分半钟,这需要太长时间。我认为这与我的 LinkedList 方法没有任何关系,因为其中没有嵌套循环。无论如何我真的可以优化这个吗?最好是比 O(n^2) 更好的东西。也许将输入数组分成两部分并进行递归调用?

//receives a lexicographically sorted string array called "input"
//some other code
//"sortAlphabetical(String)" is a sorting algorithm which lexicographically sorts a string. Used to compare two strings, uses a quick sort and is very fast... doesn't appear to be the issue.


        ArrayList<LinkedList> theList = new ArrayList<>();  //creates new linked lists for elements of the arraylist
        for(int k = 0; k < input.length; k++) {
            theList.add(new LinkedList());
        }
        int numberOfLists = 0;                      //tracks the number of non empty lists created, not relevant
        long startTime = System.nanoTime();         //begin tracking time
        for(int i = 0; i < input.length; i++) {
            String theKey = input[i];
            for(int j = 0; j < theList.size(); j++) {

                if(theList.get(j).getHeadM() != null) {

                    if(sortAlphabetical(theList.get(j).getHeadM()).equals(sortAlphabetical(theKey))) {
                        theList.get(j).add(theKey);
                        break;
                    }
                }
                else if(theList.get(j).getHeadM() == null){

                    theList.get(j).add(theKey);
                    numberOfLists++;
                    break;
                }
            }
        }

        elapsed = System.nanoTime() - startTime;
        System.out.println("The nested for loops in sortList ran. It took " + elapsed + " nanoseconds.");
//more code

我得到以下输出:

The nested for loops in sortList ran. It took 117061964600 nanoseconds.

这大约是 120 秒或两分钟。任何帮助或建议将不胜感激。如果我需要添加更多信息,请告诉我。

编辑: 我不允许使用 Java 库排序,例如哈希集等。

【问题讨论】:

  • 我认为你将优化它的方式是找到一个不同的算法。从我所看到的情况来看,您并没有真正在这里进行排序。你想完成什么?
  • 请注意,诸如“接收一个按字典顺序排序的名为“input”的字符串数组”之类的词可以直接用代码传达。 void sortList(List&lt;String&gt; input) 之类的东西或任何实际签名已经告诉我们很多。当然,假设输入列表已经排序的注释也有助于澄清。
  • @Code-Apprentice 是的,这就是我将排序放在引号中的原因,因为我真的不知道该怎么称呼它。我根据我所说的要求对 LinkedLists 列表进行“排序”。我想获得更好的运行时间,因为 2 分钟似乎太长了,即使对于 15000 个字符也是如此。我需要帮助找到一种更好的方法来实现与我的嵌套 for 循环相同的效果,但不使用嵌套循环,因为它们会提供 O(n^2) 运行时间。
  • 究竟是什么意思,数组的每个标题都必须按原始列表的字母顺序排列。它必须是任一,按字母顺序 原始顺序。您的示例输入很不幸,因为它没有区分这一点。例如,如果输入是{"car", "bed", "xylophone", "arc", "deb"},输出会是什么?
  • @Bohemian 正如我所提到的,原始列表按字母顺序排序。假设我们逐行打印出链表数组。每个“行”的第一个单词是每个列表的标题,该行由原始列表中的所有单词组成,原始列表是标题的变位词。从上到下查看时,每行的标题或每个“第一个单词”必须按字母顺序排列。希望这可以澄清事情。

标签: java arrays sorting linked-list nested-loops


【解决方案1】:
for(int i = 0; i < input.length; i++) {
String theKey = input[i];
for(int j = 0; j < theList.size(); j++) {

通过考虑获取条件表达式右侧的需要,您可以在 for 循环中获得更好的性能。

int inputLength = input.length;
int theListSize = theList.size();
for(int i = 0; i < inputLength; i++) {
String theKey = input[i];
for(int j = 0; j < theListSize; j++) {

这将在检查条件时保存每次迭代的方法调用。

【讨论】:

    猜你喜欢
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    • 2013-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-09
    • 1970-01-01
    相关资源
    最近更新 更多