【问题标题】:How to find Intersections in two singly linked lists如何在两个单链表中找到交点
【发布时间】:2013-11-25 01:52:00
【问题描述】:

我正在编写一个程序,我必须在其中设置数据结构字典(单链表),其中的单词按字母顺序排列(单词出现在带有文档 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 了。如果有人可以帮助我,我将不胜感激,我迫切希望完成这门课,而不必再接受这位教授。

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

【问题讨论】:

    标签: java dictionary intersection singly-linked-list


    【解决方案1】:
    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);
             }
            }
    

    【讨论】:

      【解决方案2】:

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

      从指向每个列表中第一个节点的指针开始。我们称他们为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 快速),要么总是在前面添加(这样你的结果是反向排序的),然后再反转列表(具有线性时间复杂度的简单操作)。

      【讨论】:

      • 非常感谢!我会将它与链接列表一起放在 testFile 类中吗?到目前为止,我的代码是否正确可以进行交叉路口?
      • 把它放在对你最有意义的地方。由于您调用了列表dictionary,您可能会考虑使其始终排序(ie 执行有序插入)。然后将intersect 方法放在dictionary 中是有意义的。否则将其放在加载和排序数据的类中。您的代码看起来不正确,这不仅仅是因为 java 中没有 end if。仔细阅读我的三个步骤。如果它没有说要推进一个特定的指针,那么你就没有。
      • 对不起,我对如何为其编写代码仍然有些困惑。
      • 能不能再过一遍。抱歉,我真的对算法感到困惑。
      • 我在答案中添加了伪代码来说明。如果您仍然感到困惑,请在纸上写出两个排序的数字列表,然后通过算法运行它们。你会明白的。
      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-12
        • 2011-01-14
        • 1970-01-01
        • 2017-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多