Например, более эффективная версия решения @ ThunderCat ,
package main
import "fmt"
func longest(a []string) []string {
var l []string
if len(a) > 0 {
l = append(l, a[0])
a = a[1:]
}
for _, s := range a {
if len(l[0]) <= len(s) {
if len(l[0]) < len(s) {
l = l[:0]
}
l = append(l, s)
}
}
return append([]string(nil), l...)
}
func main() {
a := []string{"aa", "aab", "bcd", "a", "cdf", "bb"}
fmt.Println(len(a), a)
l := longest(a)
fmt.Println(len(l), cap(l), l)
}
Детская площадка: https://play.golang.org/p/JTvl4wVvSEK
Вывод:
6 [aa aab bcd a cdf bb]
3 4 [aab bcd cdf]
Чтение @ решения ThunderCat , есть возможности для улучшения.Например, для проблем с максимумом и минимумом избегайте использования специальных значений в качестве начального максимального или минимального значения.Не перераспределяйте память и не оставляйте висячие указатели.
Go string
реализован следующим образом:
type stringStruct struct {
str unsafe.Pointer
len int
}
Если список состоит из 1000 строк длиной 1000, за которыми следует одинстрока длиной 1 001, возвращаемый список будет иметь длину один и емкость не менее 1000.999 записей имеют висячие указатели на 1000 строк байтов, которые Go gc не сможет освободить, тратя более одного мегабайта.
package main
import (
"fmt"
"strings"
"unsafe"
)
type stringStruct struct {
str unsafe.Pointer
len int
}
func main() {
var l []string
for n := 0; n < 1000; n++ {
l = append(l, strings.Repeat("x", 1000))
}
l = l[:0]
l = append(l, strings.Repeat("y", 1001))
over := (cap(l) - len(l)) * int(unsafe.Sizeof(stringStruct{}))
for i, o := len(l), l[:cap(l)]; i < cap(l); i++ {
over += len(o[i])
}
fmt.Println(over) // 1015368 bytes 64-bit, 1007184 bytes 32-bit
}
Детская площадка: https://play.golang.org/p/Fi7EgbvdVkp
Для программычтобы быть правильным, он должен быть читаемым.Во-первых, напишите фундаментальные алгоритмы без отвлечения ошибок или особых случаев.
var l []string
for _, s := range a {
if len(l[0]) <= len(s) {
if len(l[0]) < len(s) {
l = l[:0]
}
l = append(l, s)
}
}
Далее добавьте особые случаи, не прерывая работу основного алгоритма.В этом случае обрабатывайте списки нулевой и одной длины.
var l []string
if len(a) > 0 {
l = append(l, a[0])
a = a[1:]
}
for _, s := range a {
if len(l[0]) <= len(s) {
if len(l[0]) < len(s) {
l = l[:0]
}
l = append(l, s)
}
}
Наконец, убедитесь, что функция эффективна как для ЦП, так и для памяти.Распределение является точным, и нет никаких висячих указателей на неиспользуемые строки.
var l []string
if len(a) > 0 {
l = append(l, a[0])
a = a[1:]
}
for _, s := range a {
if len(l[0]) <= len(s) {
if len(l[0]) < len(s) {
l = l[:0]
}
l = append(l, s)
}
}
return append([]string(nil), l...)