在Go中找到两个整数之间的最小值的正确方法是什么?

时间:2014-12-17 00:22:03

标签: go

我在我的程序中导入了数学库,我试图通过以下方式找到最少三个数字:

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

5 个答案:

答案 0 :(得分:43)

不,我认为写这样的东西很好:例如,the stdlib's sort.go靠近文件的顶部:

func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}

math.Min(2, 3)的工作原因是numeric constants in Go are untyped。除了避免不必要的转换之外,最好不要对整数使用float函数,因为不是每个int64都有一个精确的float64表示(ones above 2^53 don't, specifically)。

答案 1 :(得分:5)

整数没有内置的min或max函数,但是编写自己的函数很简单。多亏了对可变参数函数的支持,我们甚至可以通过一次调用来比较更多整数:

func MinOf(vars ...int) int {
    min := vars[0]

    for _, i := range vars {
        if min > i {
            min = i
        }
    }

    return min
}

用法:

MinOf(3, 9, 6, 2)

类似地,这里是max函数:

func MaxOf(vars ...int) int {
    max := vars[0]

    for _, i := range vars {
        if max < i {
            max = i
        }
    }

    return max
}

答案 2 :(得分:4)

例如,

package main

import "fmt"

func min(x, y int) int {
    if x < y {
        return x
    }
    return y
}

func main() {
    t := "stackoverflow"
    v0 := make([]int, len(t)+1)
    v1 := make([]int, len(t)+1)
    cost := 1
    j := 0

    v1[j+1] = min(v1[j]+1, min(v0[j+1]+1, v0[j]+cost))

    fmt.Println(v1[j+1])
}

输出:

1

答案 3 :(得分:1)

尽管这个问题已经很老了,但也许我的包裹imath对于不喜欢重造自行车的人可能会有帮助。函数很少,很少找到两个整数:ix.Min(对于int),i8.Min(对于int8),ux.Min(对于{{1} }) 等等。可以使用uint获取该程序包,该程序包通过URL和称为go get的函数导入到您的项目中,例如:

typeabbreviation.FuncName

答案 4 :(得分:0)

可以使用https://github.com/pkg/math

import (
    "fmt"
    "github.com/pkg/math"
)

func main() {
    a, b := 45, -42
    fmt.Println(math.Min(a, b)) // Output: -42
}