我在我的程序中导入了数学库,我试图通过以下方式找到三个数字中的最小值:v1[j+1] = math.Min(v1[j]+1, math.Min(v0[j+1]+1, v0[j]+cost))
其中v1被声明为:
t := "stackoverflow"
v1 := make([]int, len(t)+1)
但是,当我运行我的程序时,我得到以下错误:
./levenshtein_distance.go:36: cannot use int(v0[j + 1] + 1) (type int) as type float64 in argument to math.Min
我觉得很奇怪因为我还有一个程序fmt.Println(math.Min(2,3))
并且该程序输出2
而没有抱怨。
所以我最终将值转换为float64,这样math.Min
就可以工作了:
v1[j+1] = math.Min(float64(v1[j]+1), math.Min(float64(v0[j+1]+1), float64(v0[j]+cost)))
使用这种方法,我得到了以下错误:
./levenshtein_distance.go:36: cannot use math.Min(int(v1[j] + 1), math.Min(int(v0[j + 1] + 1), int(v0[j] + cost))) (type float64) as type int in assignment
所以为了解决这个问题,我只是将结果强制转换回int
我认为这是非常低效和难以阅读:
v1[j+1] = int(math.Min(float64(v1[j]+1), math.Min(float64(v0[j+1]+1), float64(v0[j]+cost))))
我还写了一个小的minInt
函数,但我认为这应该是不必要的,因为其他使用math.Min
的程序在处理整数时工作得很好,所以我得出结论,这是我的程序的问题,而不是库本身的问题。
我做错什么了吗?
这里有一个程序,你可以用它来重现上面的问题,特别是第36行:主程序包
import (
"math"
)
func main() {
LevenshteinDistance("stackoverflow", "stackexchange")
}
func LevenshteinDistance(s string, t string) int {
if s == t {
return 0
}
if len(s) == 0 {
return len(t)
}
if len(t) == 0 {
return len(s)
}
v0 := make([]int, len(t)+1)
v1 := make([]int, len(t)+1)
for i := 0; i < len(v0); i++ {
v0[i] = i
}
for i := 0; i < len(s); i++ {
v1[0] = i + 1
for j := 0; j < len(t); j++ {
cost := 0
if s[i] != t[j] {
cost = 1
}
v1[j+1] = int(math.Min(float64(v1[j]+1), math.Min(float64(v0[j+1]+1), float64(v0[j]+cost))))
}
for j := 0; j < len(v0); j++ {
v0[j] = v1[j]
}
}
return v1[len(t)]
}
8条答案
按热度按时间gfttwv5a1#
在Go 1.18之前,一次性函数是标准方法;例如,the stdlib's sort.go在文件顶部附近执行:
您可能仍然希望或需要使用这种方法,以便您的代码可以在1.18以下的Go版本上运行!
从Go 1.18开始,你可以写一个generic
min
function,它在运行时和手工编码的单类型版本一样高效,但是可以使用<
和>
操作符处理任何类型:已经有discussion的更新stdlib来添加现有函数的泛型版本,但如果发生这种情况,则要等到更高版本。
math.Min(2, 3)
碰巧工作了,因为numeric constants in Go are untyped。不过,一般要注意将float 64视为通用数字类型,因为如果转换为float 64,则大于2^53
的整数将被舍入。qyuhtwio2#
对于整数没有内置的min或max函数,但编写自己的函数很简单。由于支持可变参数函数,我们甚至可以通过一次调用来比较更多的整数:
用途:
下面是max函数:
aurhwmvo3#
比如说
输出:
blmhpbnm4#
正如公认的答案所述,随着go1.18中泛型的引入,现在可以编写一个泛型函数,为不同的数值类型提供min/max(语言中没有内置)。使用可变参数,我们可以支持比较2个元素或更长的元素列表。
示例调用:
kyxcudwk5#
虽然这个问题已经很老了,但也许我的imath包对那些不喜欢重新发明自行车的人有所帮助。有几个函数,找到两个整数的最小值:
ix.Min
(对于int
)、i8.Min
(对于int8
)、ux.Min
(对于uint
)等等。该软件包可以通过go get
获得,通过URL和引用为typeabbreviation.FuncName
的函数导入到项目中,例如:j13ufse26#
可以使用https://github.com/pkg/math:
fkaflof67#
如果你想要一组N个整数中的最小值,你可以使用(假设N > 0):
其中,
min
函数的第二个参数是less
函数,即决定传入切片的元素i
何时小于元素j
的函数在Go Playground中查看:https://go.dev/play/p/lyQYlkwKrsA
dluptydi8#
在issue 59488之后,Go 1.21 (Q3 2023)将包括两个新的内置命令,如CL 498495所示:
如下所述:
最小和最大
内置函数
min
和max
分别计算固定数量的有序类型参数的最小值或最大值。必须至少有一个参数。
适用与运算符相同的类型规则:
x
和y
,如果x + y
有效,则min(x, y)
有效,并且min(x, y)
的类型是x + y
的类型(对于max也是如此)。对于数值参数,min和max是可交换的和关联的: