在列表中查找最小的数字

时间:2018-11-07 00:45:12

标签: arrays go slice

我用Go语言编写了一个程序,该程序可以找到列表中最小的数字,并且可以正常工作。 但是,我不太了解逻辑。您能否解释一下它是如何工作的?

package main

import "fmt"

func main() {
    x := []int{
        48, 96, 86, 68,
        57, 82, 63, 70,
        37, 34, 83, 27,
        19, 97, 9, 17,
    }

    for i, num := range x {
        if num < i {
            fmt.Println(num)
        }
    }
}

游乐场:https://play.golang.org/p/Awuw2Th1g2V

输出:

9

我的教科书中的解决方案是不同的,我理解那里的逻辑。

4 个答案:

答案 0 :(得分:1)

for i, num := range x {
        if num < i {
            fmt.Println(num)
        }
    }

在这里,i代表索引,num代表值。因此,您的if条件表示值小于索引,然后打印该值。例如,9的值是9且索引是14。因此它将输出9,这不是您想要执行的操作。

答案 1 :(得分:1)

要在列表中找到最小的号码,您需要遍历列表并存储当前找到的最小的号码。将这个“最小的”数字与列表中的其他数字进行比较,如果找到较小的数字,请用它替换最小的数字。在迭代结束时,您将知道列表中最小的数字。

smallest := x[0]            // set the smallest number to the first element of the list
for _, num := range x[1:] { // iterate over the rest of the list
    if num < smallest {     // if num is smaller than the current smallest number
        smallest = num      // set smallest to num
    }
}
fmt.Println(smallest)

答案 2 :(得分:1)

进一步扩展@hoque的答案:您提供的示例程序的事实纯属巧合。如果正确的值9是切片中的第一个,则根本没有输出。

有多种方法可以实现识别最小整数的目标(还有更多方法):

func smallestOfCopyWithSort(in []int) int {

  // Make a copy, so we do not have to modify the original slice.
  // Note: Do NOT use this approach, it is here only for completeness.
  copy := append([]int(nil), in...)
  sort.Ints(copy)
  return (copy[0])
}

func smallestWithSort(in []int) int {
  // Sort the slice.
  // Note that it will be modified and you
  // need to make sure that it will always
  // be sorted, even when you add new values.
  sort.Ints(in)
  return (in[0])
}

func smallestWithMattsApproach(in []int) int {
  smallest := in[0]            // set the smallest number to the first element of the list

  for _, num := range in[1:] { // iterate over the rest of the list
    if num < smallest { // if num is smaller than the current smallest number
      smallest = num // set smallest to num
    }
  }

  return smallest
}

@Matt's approach可能是最好的选择,因为它速度很快,无需修改原始切片。这实际上取决于您要实现的目标。这是一些基准测试

$ go test -test.benchmem -bench=. -test.cpu 1,2,4 -test.benchtime=10s
goos: darwin
goarch: amd64
pkg: <redacted>
BenchmarkSortWithCopy          5000000       345 ns/op       160 B/op          2 allocs/op
BenchmarkSortWithCopy-2        5000000       354 ns/op       160 B/op          2 allocs/op
BenchmarkSortWithCopy-4        5000000       352 ns/op       160 B/op          2 allocs/op
BenchmarkMattsApproach       100000000      15.1 ns/op         0 B/op          0 allocs/op
BenchmarkMattsApproach-2     100000000      15.1 ns/op         0 B/op          0 allocs/op
BenchmarkMattsApproach-4     100000000      15.2 ns/op         0 B/op          0 allocs/op
BenchmarkSort               2000000000      0.00 ns/op         0 B/op          0 allocs/op
BenchmarkSort-2             2000000000      0.00 ns/op         0 B/op          0 allocs/op
BenchmarkSort-4             2000000000      0.00 ns/op         0 B/op          0 allocs/op

毫不奇怪,如果多次调用,smallestOfCopyWithSort比其他方法要慢几个数量级。

Matts方法正在迅速发展,并且不会复制或修改任何内容。

但是,如果您需要多次访问最小数量的切片,则对切片进行排序(升序)并仅访问第一个成员会更有效。这样做的原因是切片将被修改为按排序顺序。但是,这种方法有一个警告:您要么非常careful when you add values to the slice,要么每次修改它都使用它,这可能会使性能优势无效,这取决于您对切片的读写比率。就我个人而言,我发现smallestWithSort是我最常使用的解决方案,因为我正在使用的切片通常不会更改。

结论

如果只需要一次访问最小的数字,或者切片值的顺序很重要,请使用Matt的方法。如果顺序无关紧要,则您需要多次访问最小的数字,则可能应该使用smallestWithSort,同时要牢记约束。

答案 3 :(得分:-1)

在python中返回列表的最小数量

def find_smallest_number(input_list):
    d=[]
    for num in input_list:
        for i in numbers:
            if num<i:
                if d==[]:
                    d.append(num)
                else:
                    for j in d:
                        if j>num:
                            d.remove(j)
                            d.append(num)
    return d