2016-02-15 107 views
1

我試圖使用Go實現聯合查找算法。我想執行不同的策略,如快速查找,快速聯盟加權快速聯盟使用一個結構UnionFind見下文。我把代碼放到一個包裝unionfind如何組織代碼包

package unionfind 

type Unionfind struct { 
    elements []int 
} 

func makeUnionfind(n int) Unionfind { 
    elements := make([]int, n) 
    for idx := range elements { 
     elements[idx] = idx 
    } 
    return Unionfind{elements} 
} 

接下來,我創建開始quick find不同策略的功能。下面的例子不起作用。但我不知道在哪裏放置策略特定的代碼,如何命名包以及如何導入公共結構類型。

// create a separate package for each strategy? 
package quickfind 

// import the structure locally? 
import ufp "./unionfind" 

// prefer methods over functions for convenience? 
func (uf *ufp.Unionfind) union(a int, b int) { 
    aroot := uf.elements[a] 
    broot := uf.elements[b] 
    for k, v := range uf.elements { 
     if v == aroot { 
      uf.elements[k] = broot 
     } 
    } 
} 

func (uf *ufp.Unionfind) connected(a int, b int) bool { 
    return uf.elements[a] == uf.elements[b] 
} 

我應如何組織我的代碼獲得快速找到算法工作,但已在UnionFind結構分開嗎?

+2

你確定這些是源文件的保存版本?這個錯誤表明'quickfind.go'文件說'package quickfind'(實際上,它看起來像你粘貼了同一個文件兩次。什麼是quickfind.go?) – JimB

+0

@JimB謝謝,我複製了第一個文件兩次。現在應該是正確的。 – sschmeck

+5

你不能在同一個文件夾中有兩個包。請閱讀https://golang.org/doc/code.html – fl0cke

回答

1

對於所有聯合查找實現,您將無法使用相同的結構。例如加權快速聯合除了元素之外還需要樹大小的數組。

你在這裏試圖實現的是讓相同的操作實現不同。這就是Go中的接口。

另外使用包導入的別名來保存幾個擊鍵並不是一個好習慣。相反,最好拿出一些好的名字,例如包名和它的interace/struct /函數名是有道理的。

我會安排在一個包中的所有算法結構如下:

package algorithms 

type UnionFind interface { 
    Union(a int, b int) 
    Connected(a int, b int) bool 
} 

func QuickFind(n int) UnionFind { 
    return &quickFind{......} 
} 

func QuickUnion(n int) UnionFind { 
    return &quickUnion{......} 
} 

type quickUnion struct { 
    .... 
} 

func (qu *quickUnion) Union(a int, b int) { 
    ... 
} 

func (qu *quickUnion) Connected(a int, b int) bool { 
    ... 
} 

type quickFind struct { 
    .... 
} 

func (qf *quickFind) Union(a int, b int) { 
    ... 
} 

func (qf *quickFind) Connected(a int, b int) bool { 
    ... 
} 
+0

我實施了你的方法。如有必要,您可以使用'Unionfind struct'作爲_embedded type_。單個軟件包的主要優點是可以在不導出它們的情況下共享功能。 – sschmeck

3

首先要做的是清楚地解釋你的問題。例如,

我想在Go中實現幾種可選的聯合發現算法。例如,快速資金,快速聯合,加權QU,路徑壓縮和加權+路徑。見Union-Find Algorithms, Princeton UniversityChapter one of Algorithms in Java by Sedgwick


模擬可能是Go crypto包,它實現了許多替代密碼散列函數。

+1

你怎麼知道我正在讀Sedgewick ;-)感謝您的鏈接。順便說一句:我認爲算法不如我想要一個結構以不同方式使用的事實重要。 – sschmeck

0

我改編了我的代碼以獲得工作解決方案。

  • 爲普通型Unionfind
  • 快速找到算法到自己的包「快速查找」與自己的文件夾
  • 提供圖書館/包unionfind導入unionfind使用GOPATH的默認方式
  • 取代功能的方法

杉木st文件是algorithms/unionfind/unionfindtype.go

package unionfind 

type Unionfind struct { 
    Elements []int 
} 

func MakeUnionfind(n int) Unionfind { 
    elements := make([]int, n) 
    for idx := range elements { 
     elements[idx] = idx 
    } 
    return Unionfind{elements} 
} 

第二個文件是algorithms/unionfind/quickfind/quickfind.go

package quickfind 

import ufp "algorithms/unionfind" 

func union(uf *ufp.Unionfind, a int, b int) { 
    aroot := uf.Elements[a] 
    broot := uf.Elements[b] 
    for k, v := range uf.Elements { 
     if v == aroot { 
      uf.Elements[k] = broot 
     } 
    } 
} 

func connected(uf *ufp.Unionfind, a int, b int) bool { 
    return uf.Elements[a] == uf.Elements[b] 
} 

感謝JimB和fl0cke的建議。