我正在做一个算法问题,我需要用Golang对它进行编码.在这个问题中,我需要按字符‘a’对给定的字符串数组进行排序.如果我需要谈谈问题的细节的话.

问题:

 Write a function that sorts a bunch of words by the number of character “a”s within the
word (decreasing order). If some words contain the same amount of character “a”s then you
need to sort those words by their lengths

输入

["aaaasd", "a", "aab", "aaabcd", "ef", "cssssssd", "fdz", "kf", "zc", "lklklklklklklklkl", "l"]

输出:

["aaaasd", "aaabcd", "aab", "a", "lklklklklklklklkl", "cssssssd", "fdz", "ef", "kf", "zc", "l"]

我的解决方案是:

func main() {

    arr := []string{"aaaasd", "a", "aab", "aaabcd", "ef", "cssssssd", "fdz", "kf", "zc", "lklklklklklklklkl", "l"}
    fmt.Println(mostFrequent(arr))
}

type FrequencyAndLength struct {
    slice        string
    mostFrequent int
    len          int
}

func mostFrequent(arr []string) []FrequencyAndLength { // assuming no
    testArray := []FrequencyAndLength{}
    for _, a := range arr {

        testArray = append(testArray, FrequencyAndLength{
            slice:        a,
            mostFrequent: strings.Count(a, "a"),
            len:          len(a),
        })

    }
    fmt.Println(testArray)
    return testArray
}


我现在正在得到a的个数和其中每个元素的长度.我需要首先按a的数字排序,如果a有偶数个,按降序排序,然后再按长度排序,但从逻辑上讲我被困在这里了.

推荐答案

使用sort.Slice()可按自定义逻辑对任何切片进行排序.此函数需要一个定义两个元素之间的"较少"关系的函数.

在您的情况下,如果一个值包含a个以上的字符,或者如果计数相等,则使用比较它们的长度.要计算子字符串,请使用strings.Count().要获得string的长度,请使用内置的len()函数,但请注意,len()返回的是UTF-8编码的字节长度,而不是符文数.对于字母,使用utf8.RuneCountInString().

例如:

in := []string{"aaaasd", "a", "aab", "aaabcd", "ef", "cssssssd", "fdz", "kf", "zc", "lklklklklklklklkl", "l"}

sort.Slice(in, func(i, j int) bool {
    s1, s2 := in[i], in[j]
    count1, count2 := strings.Count(s1, "a"), strings.Count(s2, "a")
    if count1 != count2 {
        return count1 > count2
    }
    return utf8.RuneCountInString(s1) > utf8.RuneCountInString(s2)
})

fmt.Println(in)

这将输出(在Go Playground上试用):

[aaaasd aaabcd aab a lklklklklklklklkl cssssssd fdz ef kf zc l]

请注意,包含相同数量的a且具有相同长度的元素之间的顺序未指定.如果希望它们的顺序与输入切片中的顺序相同,请使用sort.SliceStable()而不是sort.Slice().

还要注意,我们的定制逻辑并不复杂,但也不是微不足道的.可以多次调用该函数来比较元素,并且可以多次传递(请求)相同的元素.如果输入的切片很大, for each 元素计算一次a的个数和符文长度可能是有益的,例如,将它们存储在MAP中,并只在less()函数中查询此预先计算的数据.

它可能是这样的:

// Pre-calculate
type info struct{ count, length int }
calculated := map[string]info{}
for _, s := range in {
    calculated[s] = info{
        count:  strings.Count(s, "a"),
        length: utf8.RuneCountInString(s),
    }
}

sort.Slice(in, func(i, j int) bool {
    inf1, inf2 := calculated[in[i]], calculated[in[j]]
    if inf1.count != inf2.count {
        return inf1.count > inf2.count
    }
    return inf1.length > inf2.length
})

这个输出是相同的.在Go Playground号公路上试试.

Go相关问答推荐

使用Gorm创建自定义连接表

Zitadel示例Go Webapp加密密钥

Go协议缓冲区导入问题

在不耗尽资源的情况下处理S3文件下载

带有一个新变量的Go冒号等于运算符

Golang String

go中跨域自定义验证的问题

命令行参数在 Golang 程序中不正确地接受为参数

Go 的垃圾收集器在使用时删除 ZeroMQ 套接字

golang 中的可变参数函数

SSH 代理,数据包长度错误

如何在 golang revel 中获取动态应用程序配置

如何在 helm 中将字符串连接到 .AsConfig 的结果?

我相信我正确地在 sRGB 和线性 RGB 之间进行了转换,那么为什么深色的结果看起来更糟呢?

具有近似约束的函数值导致的实例化失败

函数调用中的类型参数panic

防止在 Go 公用文件夹中列出目录

如何将实际上是类型为 reflect.Int32 的类型切片的 interface{} 转换为 int32 的切片?

即使没有竞争条件也没有得到任何输出

获取单调时间,同 CLOCK_MONOTONIC