golang中是否有一个内置的min函数,用于一个int参数切片或一个可变数量的int参数?

nlejzf6q  于 2023-02-06  发布在  Go
关注(0)|答案(9)|浏览(145)

前兆:我刚开始被戈兰弄湿脚。
这可能被证明是一个愚蠢的问题,因为它是很容易执行这些计算,但我还是要问它,因为我没有找到答案时,谷歌。
是否有一个内置函数返回一个int参数切片的最小值:

func MinIntSlice(v []int) (m int) {
    if len(v) > 0 {
        m = v[0]
    }
    for i := 1; i < len(v); i++ {
        if v[i] < m {
            m = v[i]
        }
    }
    return
}

或可变数量的int参数的最小值:

func MinIntVarible(v1 int, vn ...int) (m int) {
    m = v1
    for i := 0; i < len(vn); i++ {
        if vn[i] < m {
            m = vn[i]
        }
    }
    return
}

如果没有,最好的“约定”是不是仅仅创建一个包含类似这样的帮助器的包?

vzgqcmou

vzgqcmou1#

这方面没有内置函数。
如果您只需要在一个包中使用此功能,则可以编写一个未导出的函数(例如minIntSlice)。
如果你需要在多个软件包中使用这个功能,你可以创建一个软件包,并将类似的功能放在那里。你应该考虑将这个软件包内部化(https://golang.org/s/go14internal)。
关于如何改进代码的一些建议:

  1. MinIntSlice对于空切片将返回0。然而0也是有效的min元素。我认为在空切片上调用panic是更好的选择。
    1.使用范围循环:
for i, e := range v {
    if i==0 || e < m {
        m = e
    }
}

如果不给出值的索引,它将给予最小值0,这可能在给定值中不存在,因此您还必须对索引应用条件。

bcs8qyzn

bcs8qyzn2#

正如@kostya正确指出的那样,Golang中没有内置的最小值或最大值函数。
不过,我建议一个稍有不同的解决方案:

func MinMax(array []int) (int, int) {
    var max int = array[0]
    var min int = array[0]
    for _, value := range array {
        if max < value {
            max = value
        }
        if min > value {
            min = value
        }
    }
    return min, max
}

这样就解决了空切片的问题:显示运行时错误(index out of range),最大值是免费的。:-)

puruo6ea

puruo6ea3#

min := s[0]
    for i :=1; i < len(s); i++ {
        if min > s[i] {
            min = s[i]
        }
    }

min > s[i]? min = s[i] : min

8qgya5xd

8qgya5xd4#

如果您不关心输入数组

import . "sort"
func MinIntSlice(v []int){
    Ints(v)
    return z[0]
}

func MaxIntSlice(v []int){
    Ints(v)
    return z[len(v)-1]
}
// and MinMax version
func MinMax(v []int)(int,int){
    Ints(v)
    return z[0],z[len(v)-1]
}
flvtvl50

flvtvl505#

This package包含MinMax函数的一些实现,用于单独的值或切片。在go get之后,可以像这样使用:

import (
    "fmt"
    "<Full URL>/go-imath/ix" // Functions for int type
)
...
fmt.Println(ix.Min(100, 152)) // Output: 100
fmt.Println(ix.Mins(234, 55, 180)) // Output: 55
fmt.Println(ix.MinSlice([]int{2, 29, 8, -1})) // Output: -1
8aqjt8rx

8aqjt8rx6#

通过排序可以缩短:

func MinIntSlice(v []int) int {
  sort.Ints(v)
  return v[0]
}

func MaxIntSlice(v []int) int {
  sort.Ints(v)
  return v[len(v)-1]
}

但是不要忘记根据你的口味修改它为零长度切片。

pzfprimi

pzfprimi7#

对于包含数百万个项目的巨大切片(例如[]int的2500万像素图像),您可以通过计算块中的最小值/最大值来获得显著的性能提升:

func GetMinMax(data []int) (int, int) {
    minVal := data[0]
    maxVal := data[0]
    for i := range data {
        if data[i] < minVal {
            minVal = data[i]
        }

        if data[i] > maxVal {
            maxVal = data[i]
        }
    }

    return minVal, maxVal
}

func GetMinMaxConcurrent(data []int) (int, int) {
    numChan := make(chan int)

    numChunks := runtime.NumCPU()
    chunkSize := len(data) / numChunks

    // Process
    var wg sync.WaitGroup
    for i := 0; i < numChunks; i++ {
        wg.Add(1)
        go func(i, chunkSize int, numChan chan int) {
            startIndex := i * chunkSize
            endIndex := startIndex + chunkSize
            if endIndex > len(data) {
                endIndex = len(data)
            }

            minVal, maxVal := GetMinMax(data[startIndex:endIndex])
            numChan <- minVal
            numChan <- maxVal
            wg.Done()
        }(i, chunkSize, numChan)
    }

    // Collect results
    resultsChan := make(chan int)
    defer close(resultsChan)

    go func(numChan, resultsChan chan int) {
        arr := make([]int, 0)
        for num := range numChan {
            arr = append(arr, num)
        }
        minVal, maxVal := GetMinMax(arr)
        resultsChan <- minVal
        resultsChan <- maxVal
    }(numChan, resultsChan)

    wg.Wait()
    close(numChan) // needed so results routine can return

    return <-resultsChan, <-resultsChan
}

这段代码对于小切片来说性能不佳,只有当切片足够大,可以从并发处理块中获益时才使用。

yhived7q

yhived7q8#

使用@kostya的answer
1.使用范围循环:

for i, e := range v {
    if i==0 || e < m {
        m = e
    }
}

如果不给出值的索引,它将给出最小值0,这在给定值中可能不存在

pprl5pva

pprl5pva9#

标准包中没有此类操作的功能。
但是,gonum library提供了floats.Min(x)floats.Max(x)函数(以及其他有趣的数字数据处理函数)。
用法:

package main

import (
    "fmt"
    "gonum.org/v1/gonum/floats"
)

func main() {
    x := []float64{1, 6, 9, -3, -5}
    minX := floats.Min(x)
    maxX := floats.Max(x)
    fmt.Printf("Min: %f, max %f\n", minX, maxX)
}

结果:

Min: -5.000000, max 9.000000

相关问题