简体   繁体   English

Java中的字符串合并排序 - 链接列表

[英]Merge Sort on Strings in Java - Linked List

I have an excercise in which I have to insert into a linked list a string. 我有一个练习,我必须在链接列表中插入一个字符串。 Suppose the String is the following: 假设字符串如下:

"Java Coding Is Great"

After the Merge Sort, the linked list is supposed to look like that: 合并排序后,链表应该看起来像这样:

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

The problem is that in my Merge Sort code I recieve the following: 问题是在我的Merge Sort代码中我收到以下信息:

 great >> is >> java >> coding 

All the words are sorted BUT THE FIRST WORD (Head of the original list) is not. 所有的单词都排序但是第一个字(原始列表的头部)不是。

I have two classes: TextList and WordNode. 我有两个类:TextList和WordNode。

The WordNode class has two attributes: WordNode类有两个属性:

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

The TextList class has only one attribute: an address of the head of the linked list: TextList类只有一个属性:链表头部的地址:

WordNode _head;

I have a constructor in which I insert the String randomly into a linked list. 我有一个构造函数,我将String随机插入到链表中。 in the end it starts merge sotring the list. 最后它开始合并sotring列表。 This algorithem is for this excercise. 这个算法是为了这个练习。

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();
}

Merge Sort Methods: mergeSort, merge and split: (These are in the WordNode class): 合并排序方法:mergeSort,merge和split :(这些在WordNode类中):

Merge Sort method 合并排序方法

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)); 
    }
}

Merge Method 合并方法

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));

    }

Split Methods: one for even positions, one for odd positions. 拆分方法:一个用于偶数位置,一个用于奇数位置。

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;
    }

Please help me figure out what's wrong. 请帮我弄清楚什么是错的。 Unfortently, I can not use a third class , and I can't use pointers to the start of the list or to the end of the list. 不幸的是,我不能使用第三类我不能使用指针列表的开头或列表的末尾。

Can you use your debugger to single-step through your code? 您可以使用调试器单步执行代码吗? That will help you pinpoint the problem. 这将有助于您找出问题所在。 Even a few judiciously placed breakpoints will help. 即使是一些明智的断点也会有所帮助。

Start with a list containing only a single entry: "Java". 从仅包含单个条目的列表开始:“Java”。 See what happens. 走着瞧吧。

Then try a two-entry list: "Java Coding". 然后尝试两个条目列表:“Java编码”。 See what happens in that case. 看看那种情况会发生什么。

Work out what is happening in the simple cases and then work up to the more complex ones. 弄清楚简单情况下发生的事情,然后处理更复杂的情况。

The problem here was a bit funny. 这里的问题有点好笑。

In my constructor I have carried a space with each word I have inserted to my list. 在我的构造函数中,我已经将每个单词插入到我的列表中。

I fixed that by this code: 我修复了这个代码:

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

instead of: 代替:

            s=text.substring(i,index);

The credit is to NormR from DevForum for the answer. 来自DevForum的NormR可以获得答案。

Nice, but I don't like your solution to merge() in WordNode. 很好,但我不喜欢你在WordNode中的merge()解决方案。 On one hand you can compare each node you prefer to like this: 一方面,您可以比较您喜欢的每个节点:

this._word.compareTo(h._word);

But in that case merge() and split() both private, so I think the better way is to put them into TextList and mergeSort() without overloading. 但是在那种情况下merge()和split()都是私有的,所以我认为更好的方法是将它们放入TextList和mergeSort()而不会重载。 You need to sort all nodes in linked list anytime you add a node, not just a part of it anyway. 您需要在添加节点时对链接列表中的所有节点进行排序,而不仅仅是其中的一部分。 That's why this 这就是为什么这个

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

and this 和这个

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

looks useless in WordNode. 在WordNode中看起来毫无用处。
On the other hand if you put your call to mergeSort into TextList like this 另一方面,如果您将对mergeSort的调用放入TextList中,就像这样

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

and mergeSort into this one in TextList 并在TextList中合并到这一个

 public WordNode mergeSort(WordNode n){

 }

it's already better but you can do even much better by reducing more time and space compexity of the way you split your list to odds and evens like this 它已经更好但是你可以做得更好,通过减少更多的时间和空间复杂性的方式将你的列表分成几率和这样的平均值

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++;
}

When you put it together you get something like this(don't forget words 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)));
}

what is left now is to finish merge() like this and again don't forget words counter 现在剩下的就是像这样完成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;
}

say hello to proffessor Rosenstein ;-) 向教授Rosenstein问好;-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM