如何使用 Golang 在结构切片中找到最频繁的整数

这是问题的总结:

  • 我试图从来自解码的 .json 文件(包含字符串“name”和整数“age”)的结构中找到最常见的“age”。

  • 之后我需要根据“年龄”的最大出现频率打印“姓名”。

  • 根据“年龄”的最大出现次数打印的“姓名”需要按字母顺序排序

输入(.json):

[

{"name": "John","age": 15},

{"name": "Peter","age": 12},

{"name": "Roger","age": 12},

{"name": "Anne","age": 44},

{"name": "Marry","age": 15},

{"name": "Nancy","age": 15}

]

输出:['John', 'Mary', 'Nancy']。

解释:因为数据中出现次数最多的年龄是 15 岁(出现 3 次),所以输出应该是一个包含三个人姓名的字符串数组,在这种情况下应该是 ['John', 'Mary', 'Nancy' ].

例外 :

  • 如果有多个“年龄”具有相同的最大出现次数,我需要拆分数据并将它们打印到不同的数组中(即当“Anne”年龄为 12 岁时,结果为:['John', 'Mary ', '南希'], ['安妮', '彼得', '罗杰']


这是我尝试过的(在 Golang 中):

package main

{

import (

    "encoding/json"

    "fmt"

    "os"

    "sort"

)

// 1. preparing the empty struct for .json

type Passanger struct {

    Name string `json:"name"`

    Age  int    `json:"age"`

}

func main() {

    // 2. load the json file

    content, err := os.ReadFile("passanger.json")

    if err != nil {

        fmt.Println(err.Error())

    }

    // 3. parse json file to slice

    var passangers []Passanger

    err2 := json.Unmarshal(content, &passangers)

    if err2 != nil {

        fmt.Println("Error JSON Unmarshalling")

        fmt.Println(err2.Error())

    }

    // 4. find most frequent age numbers (?)

    for _, v := range passangers {

        // this code only show the Age on every line

        fmt.Println(v.Age)

    }

    // 5. print the name and sort them apabethically (?)

       // use sort.slice package

       // implement group based by "max-occurence-age"

}

从昨天开始就卡住了,我还尝试从许多编码挑战问题中实施解决方案,例如:


func majorityElement(arr int) int {

    sort.Ints(arr)

    return arr[len(arr)/2]

}

但我仍在努力理解如何将 Passanger 切片中的“年龄”值作为整数输入 (arr int) 处理到上面的代码中。


我在网上找到的其他解决方案是通过迭代 map[int]int 来找到最大频率:


func main(){

    arr := []int{90, 70, 30, 30, 10, 80, 40, 50, 40, 30}

    freq := make(map[int]int)

    for _ , num :=  range arr {

        freq[num] = freq[num]+1

    }

    fmt.Println("Frequency of the Array is : ", freq)

}

但话又说回来,.json 文件不仅包含整数(年龄),还包含字符串(名称)格式,我仍然不知道如何分别处理“名称”和“年龄”..


我真的需要一个适当的指导。


*** 这是我上面提到的源代码 (main.go) 和 (.json) 文件: https: //github.com/ariejanuarb/golang-json


慕妹3242003
浏览 118回答 2
2回答

白衣非少年

在实施解决方案之前要做什么在我大学的第一年,我的老师总是对我和我的同学们重复一些事情,不要先写代码,特别是如果你是初学者,请按照以下步骤操作:写下你想要发生的事将问题详细化为小步骤写出分支时的所有场景和案例写入输入和输出(方法/函数签名)检查它们是否适合彼此让我们按照这些步骤...写下你想要发生的事你已经很好地定义了你的问题,所以我将跳过这一步。让我们进一步详细说明你有一份乘客名单你想按年龄对乘客进行分组你想看看哪些是最常见的/哪些乘客最多。你想按字母顺序打印名字分支出场景一:一个组的规模比其他所有组都大。情况二:两个或多个组具有相同的大小并且比其他组大。可能会有更多的场景,但它们是你的输入输出 ??现在我们已经知道我们必须做什么,我们将检查每个步骤的输入和输出以实现这个目标。步骤:你有一份乘客名单输入 => 无或文件名(字符串)输出=> []乘客你想按年龄对乘客进行分组input => []Passenger // 乘客列表output => map[int][]int 或 map[int][]&Passenger // ageGroups第一种,括号内的是全组年龄。第二种类型是一个列表,其中包含:乘客在列表中的位置物体/乘客在内存中的地址这并不重要,只要我们可以轻松地从列表中取回乘客而无需再次迭代即可。你想看看哪些是最常见的/哪些乘客最多。输入 => 组(年龄组)所以这里我们有场景 1 和场景 2 的分支......这意味着它必须对所有场景都有效或使用条件将它们分支出来。场景 1 的输出 => 最常见的年龄 (int)场景 2 的输出 => 最常见的年龄 ([]int)我们可以看到场景 1 的输出可以与场景 2 的输出合并您想要按年龄组中所有乘客的字母顺序打印姓名老实说,如果你愿意,你可以跳过这个。input => groups ([]Passenger) + ages ([]int) + passenger list ([]Passenger).output => string or []byte or nothing if you just print it...检查后,是时候编码了让我们首先创建适合我们签名的功能type Passenger struct {&nbsp; &nbsp; Name string `json:"name"`&nbsp; &nbsp; Age&nbsp; int&nbsp; &nbsp; `json:"age"`}func GetPassengerList() []Passenger{&nbsp; &nbsp;// 2. load the json file&nbsp; &nbsp;content, err := os.ReadFile("passanger.json")&nbsp; &nbsp;if err != nil {&nbsp; &nbsp; &nbsp; &nbsp;fmt.Println(err.Error())&nbsp; &nbsp;}&nbsp; &nbsp;// 3. parse json file to slice&nbsp; &nbsp;var passengers []Passenger&nbsp;&nbsp; &nbsp;err2 := json.Unmarshal(content, &passengers)&nbsp; &nbsp;if err2 != nil {&nbsp; &nbsp; &nbsp; &nbsp;fmt.Println("Error JSON Unmarshalling")&nbsp; &nbsp; &nbsp; &nbsp;fmt.Println(err2.Error())&nbsp; &nbsp;}&nbsp; &nbsp;return passengers}// 4a. Group by Agefunc GroupByAge(passengers []Passenger) map[int][]int {&nbsp; &nbsp; group := make(map[int][]int, 0)&nbsp; &nbsp; for index, passenger := range passengers {&nbsp; &nbsp; &nbsp; &nbsp; ageGroup := group[passenger.Age]&nbsp; &nbsp; &nbsp; &nbsp; ageGroup = append(ageGroup, index)&nbsp; &nbsp; &nbsp; &nbsp; group[passenger.Age] = ageGroup&nbsp; &nbsp; }&nbsp; &nbsp; return group}// 4b. find the most frequent age numbersfunc FindMostCommonAge(ageGroups map[int][]int) []int {&nbsp; &nbsp; mostFrequentAges := make([]int, 0)&nbsp; &nbsp; biggestGroupSize := 0&nbsp; &nbsp; // find most frequent age numbers&nbsp; &nbsp; for age, ageGroup := range ageGroups {&nbsp; &nbsp; &nbsp; &nbsp; // is most frequent age&nbsp; &nbsp; &nbsp; &nbsp; if biggestGroupSize < len(ageGroup) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; biggestGroupSize = len(ageGroup)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mostFrequentAges = []int{age}&nbsp; &nbsp; &nbsp; &nbsp; } else if biggestGroupSize == len(ageGroup) { // is one of the most frequent age&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mostFrequentAges = append(mostFrequentAges, age)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // is not one of the most frequent age so does nothing&nbsp; &nbsp; }&nbsp; &nbsp; return mostFrequentAges}func main() {&nbsp; &nbsp; passengers := loadPassengers()&nbsp; &nbsp; // I am lazy but if you want you could sort the&nbsp; &nbsp; // smaller slice before printing to increase performance&nbsp; &nbsp; sort.Slice(passengers, func(i, j int) bool {&nbsp; &nbsp; &nbsp; &nbsp; if passengers[i].Age == passengers[j].Age {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return passengers[i].Name < passengers[j].Name&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return passengers[i].Age < passengers[j].Age&nbsp; &nbsp; })&nbsp; &nbsp; // age => []position&nbsp; &nbsp; // Length of the array count as the number of occurences&nbsp; &nbsp; ageGrouper := GroupByAge(passengers)&nbsp; &nbsp; mostFrequentAges := FindMostCommonAge(ageGrouper)&nbsp; &nbsp; // print the passenger&nbsp; &nbsp; for _, age := range mostFrequentAges {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("{")&nbsp; &nbsp; &nbsp; &nbsp; for _, passengerIndex := range ageGrouper[age] {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("\t", passengers[passengerIndex].Name)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("}")&nbsp; &nbsp; }}

冉冉说

应该比任何更复杂按年龄和名称对源切片进行排序将其分解成具有共同年龄的序列,并且在进行过程中,跟踪最常见的是这样的:https://goplay.tools/snippet/6pCpkTEaDXNtype Person struct {&nbsp; &nbsp; Age&nbsp; int&nbsp; &nbsp; Name string}func MostCommonAge(persons []Person) (mostCommonAge int, names []string) {&nbsp;&nbsp;&nbsp; sorted := make([]Person, len(persons))&nbsp; copy(sorted, persons)&nbsp;&nbsp;&nbsp; // sort the slice by age and then by name&nbsp; sort.Slice(sorted, func(x, y int) bool {&nbsp; &nbsp; left, right := sorted[x], sorted[y]&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; switch {&nbsp; &nbsp; case left.Age < right.Age:&nbsp; &nbsp; &nbsp; return true&nbsp; &nbsp; case left.Age > right.Age:&nbsp; &nbsp; &nbsp; return false&nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; return left.Name < right.Name&nbsp; &nbsp; }&nbsp; })&nbsp; updateMostCommonAge := func(seq []Person) (int, []string) {&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; if len(seq) > len(names) {&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; buf := make([]string, len(seq))&nbsp; &nbsp; &nbsp; for i := 0; i < len(seq); i++ {&nbsp; &nbsp; &nbsp; &nbsp; buf[i] = seq[i].Name&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; mostCommonAge = seq[0].Age&nbsp; &nbsp; &nbsp; names = buf&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; }&nbsp; &nbsp; return mostCommonAge, names&nbsp;&nbsp;&nbsp; }&nbsp; for lo, hi := 0, 0; lo < len(sorted); lo = hi {&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; for hi = lo; hi < len(sorted) && sorted[lo].Age == sorted[hi].Age; {&nbsp; &nbsp; &nbsp; hi++&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; mostCommonAge, names = updateMostCommonAge(sorted[lo:hi])&nbsp; &nbsp;&nbsp;&nbsp; }&nbsp; return mostCommonAge, names}另一种方法使用更多内存,但更简单一些。在这里,我们按年龄构建了一个名字映射,然后对其进行迭代以找到具有最长名字列表的键。https://goplay.tools/snippet/_zmMys516IMtype Person struct {&nbsp; &nbsp; Age&nbsp; int&nbsp; &nbsp; Name string}func MostCommonAge(persons []Person) (mostCommonAge int, names []string) {&nbsp; &nbsp; namesByAge := map[int][]string{}&nbsp; &nbsp; for _, p := range persons {&nbsp; &nbsp; &nbsp; &nbsp; value, found := namesByAge[p.Age]&nbsp; &nbsp; &nbsp; &nbsp; if !found {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value = []string{}&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; namesByAge[p.Age] = append(value, p.Name)&nbsp; &nbsp; }&nbsp; &nbsp; for age, nameList := range namesByAge {&nbsp; &nbsp; &nbsp; &nbsp; if len(nameList) > len(names) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mostCommonAge, names = age, nameList&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return mostCommonAge, names}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go