dongyi0210 2014-12-17 00:22
浏览 625
已采纳

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

I imported the math library in my program, and I was trying to find the minimum of three numbers in the following way:

v1[j+1] = math.Min(v1[j]+1, math.Min(v0[j+1]+1, v0[j]+cost))

where v1 is declared as:

t := "stackoverflow"
v1 := make([]int, len(t)+1)

However, when I run my program I get the following error:

./levenshtein_distance.go:36: cannot use int(v0[j + 1] + 1) (type int) as type float64 in argument to math.Min

I thought it was weird because I have another program where I write

fmt.Println(math.Min(2,3))

and that program outputs 2 without complaining.

so I ended up casting the values as float64, so that math.Min could work:

v1[j+1] = math.Min(float64(v1[j]+1), math.Min(float64(v0[j+1]+1), float64(v0[j]+cost)))

With this approach, I got the following error:

./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

so to get rid of the problem, I just casted the result back to int

I thought this was extremely inefficient and hard to read:

v1[j+1] = int(math.Min(float64(v1[j]+1), math.Min(float64(v0[j+1]+1), float64(v0[j]+cost))))

I also wrote a small minInt function, but I think this should be unnecessary because the other programs that make use of math.Min work just fine when taking integers, so I concluded this has to be a problem of my program and not the library per se.

Is there anything that I'm doing terrible wrong?

Here's a program that you can use to reproduce the issues above, line 36 specifically: package main

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)]
}
  • 写回答

3条回答 默认 最新

  • drxkx6149 2014-12-17 00:40
    关注

    Nope, I think writing something like that is fine: for instance, the stdlib's sort.go does it near the top of the file:

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

    Your math.Min(2, 3) worked because numeric constants in Go are untyped. Besides just avoiding unnecessary casting, it seems best practice not to use float functions for integers because not every int64 has a precise float64 representation (ones above 2^53 don't, specifically).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥20 基于MSP430f5529的MPU6050驱动,求出欧拉角
  • ¥20 Java-Oj-桌布的计算
  • ¥15 powerbuilder中的datawindow数据整合到新的DataWindow
  • ¥20 有人知道这种图怎么画吗?
  • ¥15 pyqt6如何引用qrc文件加载里面的的资源
  • ¥15 安卓JNI项目使用lua上的问题
  • ¥20 RL+GNN解决人员排班问题时梯度消失
  • ¥60 要数控稳压电源测试数据
  • ¥15 能帮我写下这个编程吗
  • ¥15 ikuai客户端l2tp协议链接报终止15信号和无法将p.p.p6转换为我的l2tp线路