如何在两个单链表中找到交点

时间:2013-11-25 01:52:00

标签: java dictionary intersection singly-linked-list

我正在编写一个程序,其中我必须设置数据结构字典(单链表),其中按字母顺序排列单词(出现在带有文档ID的文本文档中的句子中的单词)。并找出哪些单词出现在多个文档中,以便教授希望我们做一个交集。我真的很困惑如何做交叉。我有其他一切(我相信这是正确的)。这是我的代码(我添加了我的交叉算法,但它显然不起作用,我遵循教授算法[她从未向我们展示过一个例子]):

public class dictionary 
{
  //variables
  dNode head;
  int size;

  //constructor
  public dictionary() 
  {
    head = null;
    size = 0;
  }

  //addFirst method
  public void addFirst(dNode s) 
  {
    s.setNext(head);
    head = s;
    size++;
  }

  public void addLast(dNode s)
  {
    if ( head == null )
    {
      head = s;
    }
    else
    {
      s.setNext(null);
      dNode w = head;
      while ( w.getNext() != null ) 
      { 
        w = w.getNext();
      }
      w.setNext(s);
    }
      size++;
  }

  //toString Method
  public String toString() 
  {
    String w = "";
    dNode s = head;
    while ( s != null ) 
    {
      w += s + "\n";
      s = s.getNext();
    }
    return w;
  }

  //intersection method
public String intersection(pNode head, dNode head) {
int left = posting.head;
int right = dictionary.head;
int result = new dictionary();

while (left != null && right != null) {
     if (dID.left < dID.right) {
     left = left.next;
else if (dID.left > dID.right)
     right = right.next;
else 
     left = left.next;
     right = right.next;
     result.push(left.data() );
     }
}
return result;
}  
}


public class dNode 
{
  //variables
  String sent;
  posting post;
  dNode nextNode;

  //constructor
  public dNode(String sent, posting post, dNode nextNode)
  {
    this.sent = sent;
    this.post = post;
    this.nextNode = nextNode;
  }

  //returns element of this node
  public String getSent() {
    return sent;
  }

  //retunrs the next node of this node
  public dNode getNext() {
    return nextNode;
  }

  //modifier methods
  //sets elements of this node.
  public void setSent(String newSent) {
    sent = newSent;
  }

  //sets the next node of this node
  public void setNext( dNode newNext) {
    nextNode = newNext;
  }
  //toString method
  public String toString() 
  {
    return "Sentence and Posting: \n" + sent + "\n" + post;
  }
}


public class pNode {
  //variables
  int dID;
  String word;
  int occurence;
  pNode next;

  //constructor
  public pNode(int dID, String word, int occurence, pNode next)
  {
    this.dID = dID;
    this.word = word;
    this.occurence = occurence;
    this.next = next;
  }
  //return element of this node
  public String getWord() {
    return word;
  }

  //Returns the next node of this node
  public pNode getNext() {
    return next;
  }

  //Modifier methods
  //set the words of this node
  public void setWord(String newWord) {
    word = newWord;
  }

  //sets the next node of this node
  public void setNext(pNode newNext){
    next = newNext;
  }

  //toString method
  public String toString() {
    return "Document ID, Word, Occurence: \n " + dID + ", " 
      + word + ", " + occurence;
  }

}


public class posting 
{
  //variables
  pNode head;
  int size;

  //constructor
  public posting() 
  {
    head = null;
    size = 0;
  }

  //addFirst method 
  public void addFirst(pNode s) 
  {
    s.setNext(head);
    head = s;
    size++;
  }

  //addLast method
  public void addLast(pNode s)
  {
    if ( head == null )
    {
      head = s;
    }
    else
    {
      s.setNext(null);
      pNode w = head;
      while ( w.getNext() != null ) 
      {
        w = w.getNext();
      }
      w.setNext(s);
    }
    size++;
  }

  //toString method
  public String toString()
  {
    String w = "";
    pNode s = head;
    while ( s != null) 
    {
      w += s + "\n";
      s = s.getNext();
    }
    return w;
  }
}

import java.io.*;
import java.util.*;

  public class testFile
  {

  public static void main (String[] args) throws FileNotFoundException 
  {
    File filename = new File("/export/home/hawkdom2/s0878044/CS503/assignment2/sentences.txt");
    Scanner scan = new Scanner(filename);
    dictionary Dictionary = new dictionary();

   while ( scan.hasNextLine() )
   {
     String sentence = scan.nextLine();
     String[] word = sentence.split(" ");

     //first element is document id
     int dID = Integer.parseInt( word[0] );

     //insertion sort
     for ( int i = 2; i < word.length; i++ )
     {
       for ( int j = i; j > 1; j-- )
       {
        if ( word[j].compareTo( word[j-1] ) > 0 )
        {
          String switchs = word[j];
          word[j] = word[j-1];
          word[j-1] = switchs;
        }
       }
     }

     //integer array count
     int[] count = new int[word.length];
     for ( int i = 1; i < word.length; i++)
     {
       for ( int j = 1; j < word.length; j++)
       {
         if (word[i].equalsIgnoreCase( word[j] ) )
         {
           count[i]++;
         }
       }
     }

     posting posts = new posting();

     for ( int i = 1; i < word.length; i++ )
     {
       if ( (i > 1 ) && (word[i].equalsIgnoreCase( word[i-1] ) ) )
         continue;
       else
       {
         posts.addFirst(new pNode(dID, word[i], count[i], null) );
       }
     }

     Dictionary.addLast(new dNode(sentence, posts, null) );
   }





   //print out output
   System.out.println(Dictionary);
  }
  }

这是句子文件:

1 a rose is a rose 
2 John chased a cat and the cat chased John
3 cats are mammals but mammals are not cats
4 beavers build dams but i know a beaver that does not
5 my dog chased a cat and the cat attacked my dog
6 my dog likes cats but my cat dislikes dogs
7 my dog likes roses but roses dislike my dog
8 my cat dislikes roses but roses like my cat
9 red roses are not my favorite roses
10 my favorite roses are pink roses

如果我能够了解如何交叉两个链接列表(或者如果我的程序有任何其他错误),我会非常感激。我上周病了,我的教授拒绝帮助我做错过的事情(显然,如果我生病时不上课,我不是一个认真的程序员)。我真的不能忍受这位教授教授这门课程的方式,因为她没有给我们任何程序的例子(而且她给我们的极少数总是有错误)。她也只是给我们算法,她已经说过,但它们并不总是正确的。我曾经喜欢编程,但她真的让我失望了,我现在要做的就是至少得到一个C所以我可以切换到IT。如果有人可以帮助我,我真的很感激,我非常渴望完成这门课程而不必再次接受这位教授。

我添加了一个交叉方法,但仍然收到所有这些错误: 找到7个错误: 文件:/export/home/hawkdom2/s0878044/CS503/assignment2/testFile.java [line:86] 错误:/export/home/hawkdom2/s0878044/CS503/assignment2/testFile.java:86:表达的非法开始 文件:/export/home/hawkdom2/s0878044/CS503/assignment2/testFile.java [line:86] 错误:/export/home/hawkdom2/s0878044/CS503/assignment2/testFile.java:86:';'预期 文件:/export/home/hawkdom2/s0878044/CS503/assignment2/testFile.java [line:86] 错误:/export/home/hawkdom2/s0878044/CS503/assignment2/testFile.java:86:不是声明 文件:/export/home/hawkdom2/s0878044/CS503/assignment2/testFile.java [line:86] 错误:/export/home/hawkdom2/s0878044/CS503/assignment2/testFile.java:86:';'预期 文件:/export/home/hawkdom2/s0878044/CS503/assignment2/testFile.java [line:86] 错误:/export/home/hawkdom2/s0878044/CS503/assignment2/testFile.java:86:不是声明 文件:/export/home/hawkdom2/s0878044/CS503/assignment2/testFile.java [line:86] 错误:/export/home/hawkdom2/s0878044/CS503/assignment2/testFile.java:86:';'预期 文件:/export/home/hawkdom2/s0878044/CS503/assignment2/testFile.java [line:96] 错误:/export/home/hawkdom2/s0878044/CS503/assignment2/testFile.java:96:'else'没有'if'

3 个答案:

答案 0 :(得分:2)

public static void findIntersection(LLNode head1, LLnode head2)
    {
        HashSet<LLNode> hs= new HashSet<>();
        HashSet<LLNode> hs2 = new HashSet<>();
        LLNode currentNode1 = head1; 

        while(currentNode.getNext()!=null)
        {
            hs.add(currentNode);
            currentNode1 = currentNode1.getNext();
        }

        LLNode currentNode2 = head2;
        while(currentNode2.getNext()!=null)
        {  
        if(hs1.contains(currentNode2)){
             hs2.add(currentNode2);
         }
        }

答案 1 :(得分:0)

交叉两个排序列表很容易。

从指向每个列表中第一个节点的指针开始。我们称他们为leftright。创建一个新的空列表,我们称之为result。现在循环,比较存储在leftright节点的数据:

  • 如果left的数据较少,请提前left
  • 如果right的数据较少,请提前right
  • 如果数据相同,请将其添加到result并提前leftright

您的循环一直持续到您阅读leftright的结尾为止。现在您已经与两个列表相交( result列表仅包含leftright中显示的元素。

function intersect( list1, list2 )
    left <- list1.head
    right <- list2.head
    result <- new list

    while left != null and right != null
        if left.data < right.data
            left <- left.next
        elseif left.data > right.data
            right <- right.next
        else
            left <- left.next
            right <- right.next
            result.push(left.data)
        end if
    end

    return result
end function

要获得最佳速度,请在列表中存储tail指针(以便addLast快速),或者始终在前面添加(因此您的结果是反向排序的)然后反向之后的列表(具有线性时间复杂度的简单操作)。

答案 2 :(得分:0)

我的版本找到两个链表的交集如下: 1.迭代第一个链表并在IdentityHashMap中添加元素作为键。 2.迭代第二个链表并进行containsKey检查。如果为true,则节点相交。

时间复杂度:O(n + m)其中n =第一列表的大小,m =第二列表的大小 空间复杂度:O(n)