2016-02-15 103 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的建议。