【问题标题】:Merge Sort on Strings in Java - Linked ListJava中字符串的合并排序 - 链表
【发布时间】:2013-06-04 17:27:21
【问题描述】:

我有一个练习,我必须在链表中插入一个字符串。假设字符串如下:

"Java Coding Is Great"

在归并排序之后,链表应该是这样的:

coding >>> great >>> is >>> java.

问题是在我的合并排序代码中我收到以下内容:

 great >> is >> java >> coding 

所有单词都已排序,但第一个单词(原始列表的开头)不是。

我有两个类:TextList 和 WordNode。

WordNode 类有两个属性:

String _word; WordNode _next; //an address to the next link

TextList类只有一个属性:链表头的地址:

WordNode _head;

我有一个构造函数,我在其中将字符串随机插入到链表中。最后它开始合并排序列表。该算法适用于本次练习。

public TextList(String text){
     String s=""; int index=text.length();
    //we will stop at the end of the String.
    for (int i=text.length()-1; i>=0; i--){
        //if we reached a space, insert each string in appropriate order, 
        //the first word is the head of the string and last word points to null.
        if (!(text.charAt(i)>='a' && text.charAt(i)<='z')){ 
            s=text.substring(i,index);
            _head=new WordNode(s,_head);
            s="";
            index=i;
        }
        if (i==1){
            s=text.substring(i-1,index);
            _head=new WordNode(s,_head);
        }
    }

//start merge sotring the list.
    this._head=this._head.mergeSort();
}

合并排序方法:mergeSort、merge 和 split:(这些在 WordNode 类中):

合并排序方法

public WordNode mergeSort(){
    return mergeSort(this);
}
private WordNode mergeSort(WordNode h){
    // Sort h by recursively splitting and merging
    if (h==null || h._next==null)
        return h;
    else{
        WordNode evens=h.splitOdds();
        WordNode odds=h.splitEvens();
        return mergeSort(odds).merge(mergeSort(evens)); 
    }
}

合并方法

private WordNode merge(WordNode h){
        //method merges this's list with h's list

        //if h is null, just return this.
        if (h==null){
            return this;
        }
        if (this._word.compareTo(h._word)<0){
            if (this._next==null)
                return new WordNode(this._word,h);
            else
                return new WordNode(this._word,this._next.merge(h));
        }
        else
            return new WordNode (h._word, merge(h._next));

    }

拆分方式:偶数一种,奇数一种。

private WordNode splitOdds(){
    boolean flag=true;
    WordNode odds=null;
    WordNode ptr=this;
    while (ptr!=null){  
        if(flag)
        odds=new WordNode(ptr._word,odds);
        ptr=ptr.getNext();
        flag=!flag;
    }
    return odds;
}
//MUST BE INITILIZED ON HEAD
    private WordNode splitEvens(){
        boolean flag=true;
        WordNode evens=null;
        WordNode ptr=this._next;
        while (ptr!=null){
            if (flag)
                evens=new WordNode(ptr._word,evens);
                ptr=ptr.getNext();
                flag=!flag;
            }



        return evens;
    }

请帮我找出问题所在。 不幸的是,我不能使用第三类我不能使用指向列表开头或结尾的指针。

【问题讨论】:

  • 多次发布同一个问题不会帮助您找到答案。请删除两者之一并等待答复。
  • @BackSlash - 我在这里取得了真正的进步,因为代码几乎可以工作。感谢您的关注 - 如何删除我之前的问题?
  • 不要删除它。改为删除这个问题,并用所有新的详细信息更新旧问题
  • @BackSlash,这没有任何意义。他为什么要删除新的问题,这个问题实际上被回答的可能性要高得多?
  • 这可能只是一个错字,但你有:this._head=this._head.mergeSort();,但你的mergeSort 方法需要WordNode

标签: java string linked-list mergesort


【解决方案1】:

您可以使用调试器单步执行您的代码吗?这将帮助您查明问题。即使是一些明智地放置断点也会有所帮助。

从只包含一个条目的列表开始:“Java”。看看会发生什么。

然后尝试一个包含两个条目的列表:“Java 编码”。看看在这种情况下会发生什么。

找出简单案例中发生的情况,然后处理更复杂的案例。

【讨论】:

  • 现在试过了......到目前为止还没有成功。也许还有其他想法?
  • 粗略的解决方案,没有找到问题的根源。在列表的开头添加一个虚假条目:“AAAAAAA”,排序然后删除虚假条目。
  • @Alan 你怎么会用调试器找不到任何东西?您是否尝试使用它并意识到您现在没有如何使用它?不是故意粗鲁,但它一定帮助你弄清楚了一些事情......
  • @Steve P。也许问题出在头部 - 合并后它一直回到链表的 END,我就是不明白为什么。
  • @rossum - 这可能有效,但我必须仔细阅读所有列表,对吧?我认为这可能有效,但正如您所建议的那样 - 不会解决问题的根源。
【解决方案2】:

这里的问题有点好笑。

在我的构造函数中,我在列表中插入的每个单词都带有一个空格。

我通过这段代码解决了这个问题:

            s=text.substring(i+1,index);

代替:

            s=text.substring(i,index);

感谢 DevForum 的 NormR 提供答案。

【讨论】:

    【解决方案3】:

    很好,但我不喜欢你在 WordNode 中的 merge() 解决方案。一方面,您可以比较您喜欢的每个节点:

    this._word.compareTo(h._word);
    

    但在这种情况下,merge() 和 split() 都是私有的,所以我认为更好的方法是将它们放入 TextList 和 mergeSort() 而不重载。每当您添加一个节点时,您都​​需要对链表中的所有节点进行排序,而不仅仅是它的一部分。这就是为什么

    this._head = this._head.mergeSort();
    

    还有这个

    public WordNode mergeSort(){
        return mergeSort(this);
    }
    

    在 WordNode 中看起来没用。
    另一方面,如果您像这样将mergeSort 调用到TextList 中

    this._head = this.mergeSort(this._head);
    

    并mergeSort到TextList中的这个

     public WordNode mergeSort(WordNode n){
    
     }
    

    它已经更好了,但您可以通过减少更多时间和空间的复杂性来将您的列表拆分为这样的奇数和偶数,从而做得更好

    int counter = 1;    //  nodes counter helps to know if the current node is odd or even
    WordNode L = null,  //  odd nodes
             R = null;  //  even nodes
    while(h != null)
    {
        if(counter%2 == 0)
            R = new WordNode(h.getWord(), R, h.getWordCounter());
        else
            L = new WordNode(h.getWord(), L, h.getWordCounter());
        //  
        h = h.getNext();
        counter++;
    }
    

    当你把它放在一起时,你会得到这样的东西(不要忘记单词计数器)

    public WordNode mergeSort(WordNode h){
        int counter = 1;    //  nodes counter helps to know if the current node is odd or even
        WordNode L = null,  //  odd nodes
                 R = null;  //  even nodes
        while(h != null)
        {
            if(counter%2 == 0)
                R = new WordNode(h.getWord(), R, h.getWordCounter());
            else
                L = new WordNode(h.getWord(), L, h.getWordCounter());
            //  
            h = h.getNext();
            counter++;
        }
        return merge(mergeSort(L), (mergeSort(R)));
    }
    

    现在剩下的就是像这样完成 merge() 并且再次不要忘记单词计数器

    private WordNode merge(WordNode L, WordNode R)
    {   
        while(L != null || R != null)
        {
            if(L != null && R != null)
                if(L.getWord().compareTo(R.getWord()) <= 0)
                    return new WordNode(L.getWord(), merge(L.getNext(), R), L.getWordCounter());
                else
                    return new WordNode(R.getWord(), merge(L, R.getNext()), R.getWordCounter());
            else if(L != null)
                return new WordNode(L.getWord(), merge(L.getNext(), R), L.getWordCounter());
            else if(R != null)
                return new WordNode(R.getWord(), merge(L, R.getNext()), R.getWordCounter());
        }
        return null;
    }
    

    向罗森斯坦教授问好 ;-)

    【讨论】:

      猜你喜欢
      • 2012-01-17
      • 2013-03-31
      • 1970-01-01
      • 2020-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-29
      相关资源
      最近更新 更多