如何最好地对这个Go DisjointSets数据结构进行鸭子类型检查?

huangapple go评论73阅读模式
英文:

How do I best duck-type this Go DisjointSets data structure?

问题

我有一个DisjointSets数据结构(从Cormen中提取),用Go语言实现,可以与int64一起使用。

type DisjointSets struct {
    ranks map[int64]int64
    p     map[int64]int64
}

// New返回一个新的DisjointSets
func NewDisjointSets() *DisjointSets {
    d := DisjointSets{map[int64]int64{}, map[int64]int64{}}
    return &d
}

// MakeSet将元素x添加到其自己的集合中
func (d *DisjointSets) MakeSet(x int64) {
    d.p[x] = x
    d.ranks[x] = 0
}

// Link根据每个元素的秩将x分配给y或反之亦然
func (d *DisjointSets) Link(x, y int64) {
    if d.ranks[x] > d.ranks[y] {
        d.p[y] = x
    } else {
        d.p[x] = y
        if d.ranks[x] == d.ranks[y] {
            d.ranks[y] += 1
        }
    }
}

// FindSet返回元素x所在的集合
func (d *DisjointSets) FindSet(x int64) int64 {
    if x != d.p[x] {
        d.p[x] = d.FindSet(d.p[x])
    }
    return d.p[x]
}

// Union将两个元素x和y合并为一个集合
func (d *DisjointSets) Union(x, y int64) {
    d.Link(d.FindSet(x), d.FindSet(y))
}

我想尽量少地编写增量代码来使用这个结构来处理float64string等类型。我该怎么做?

到目前为止我尝试了什么

我已经阅读了关于接口的所有内容,但似乎我不明白如何在不必为每种类型编写完整实现的情况下应用它。

英文:

I have a DisjointSets data structure (pulled from Cormen), implemented in Go to work with int64.

type DisjointSets struct {
	ranks map[int64]int64
	p map[int64]int64
}

// New returns a new DisjointSets
func NewDisjointSets() *DisjointSets {
	d := DisjointSets{map[int64]int64{}, map[int64]int64{}}
	return &d
}

// MakeSet adds element x to the disjoint sets in its own set
func (d *DisjointSets) MakeSet(x int64) {
	d.p[x] = x
	d.ranks[x] = 0
}

// Link assigns x to y or vice versa, depending on the rank of each
func (d *DisjointSets) Link(x, y int64) {
	if d.ranks[x] > d.ranks[y] {
		d.p[y] = x
	} else {
		d.p[x] = y
		if d.ranks[x] == d.ranks[y] {
			d.ranks[y] += 1
		}
	}
}

// FindSet returns the set in which an element x sits
func (d *DisjointSets) FindSet(x int64) int64 {
	if x != d.p[x] {
		d.p[x] = d.FindSet(d.p[x])
	}
	return d.p[x]
}

// Union combines two elements x and y into one set.
func (d *DisjointSets) Union(x, y int64) {
	d.Link(d.FindSet(x), d.FindSet(y))
}

I'd like to write as little incremental code as possible to use this structure for float64, string, etc. How do I do this?

What I've tried so far

I've read everything I can about Interfaces, but I just don't seem to understand how to apply it without having to write a complete implementation for each type.

答案1

得分: 1

Go语言没有模板,所以我认为没有一种优雅的方法来实现这个。你可以尝试将类(class)的参数类型从int64改为interface{}。

英文:

Go does not have templates so I do not think there is an elegant way to do this. You might try changing the class to take interface{} instead of int64.

答案2

得分: 1

在使用接口时,你遇到了什么问题?你应该能够轻松地将代码转换为使用interface{}作为元素类型,并使其适用于任何具有相等性定义的类型(可以作为映射键使用)。

大致如下:

英文:

What was the issue you stumbled upon when using interfaces? You should be able to easily translate that code to use interface{} as the element types and have it working with any type that has equality defined for it (can work as map keys).

Something along the lines of:

答案3

得分: 0

看起来你正在尝试实现经典的并查集算法。

为什么不保留你已有的代码,然后在其上添加一个从任意类型(如float64string等)到int64的映射呢?这样你就不需要改变原始代码了,可以考虑使用组合。

具体来说,添加一个从你想要的领域(比如string)到整数的映射:

var m1 map[string]int64
...
m1["hello"] = 0
m2["world"] = 1

然后,每当你想要确定元素属于哪个集合时,使用m1将字符串转换为其整数表示,然后使用你的原始代码找到代表元素。

英文:

Looks like you're trying to implement the classical union-find algorithm.

Why can't you keep what you've got, and just layer on top of this a mapping from whatever thing you want (float64, string, etc.) to an int64? Then you don't have to change your original code at all. Think composition.

Concretely, add a map from whatever domain you want, like string:

var m1 map[string]int64
...
m1["hello"] = 0
m2["world"] = 1

and then, whenever you want to figure out what set it belongs to, use m1 to go from strings to its integer representation for the element, and then your original code to find the parent representative.

huangapple
  • 本文由 发表于 2013年9月12日 10:50:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/18754531.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定