簡體   English   中英

如何在兩個單鏈表中找到交點

[英]How to find Intersections in two singly linked lists

我正在編寫一個程序,其中我必須設置數據結構字典(單鏈表),按字母順序排列單詞(出現在帶有文檔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:'其他'沒有'如果'

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

相交兩個排序列表很容易。

從指向每個列表中第一個節點的指針開始。 讓我們稱他們為leftright 創建一個新的空列表,讓我們稱之為result 現在你循環,將存儲在數據leftright節點:

  • 如果left的數據較少,則left前進。
  • 如果right的數據較少,則right前進。
  • 如果數據是平等的,把它添加到result和推進兩leftright

你的循環繼續,直到你讀到leftright的結尾。 現在您已經交叉了兩個列表( result列表僅包含left right出現的元素)。

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快速),或者始終在前面添加(因此您的結果是反向排序的)然后反轉列表(使用線性時間的簡單操作 -復雜)。

我的版本找到兩個鏈表的交集如下:1。迭代第一個鏈表並在IdentityHashMap中添加元素作為鍵。 2.迭代第二個鏈表並進行containsKey檢查。 如果為true,則節點相交。

時間復雜度:O(n + m)其中n =第一個列表的大小,m =第二個列表的大小空間復雜度:O(n)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM