2 回答

TA貢獻(xiàn)1155條經(jīng)驗(yàn) 獲得超0個(gè)贊
在實(shí)施解決方案之前要做什么
在我大學(xué)的第一年,我的老師總是對我和我的同學(xué)們重復(fù)一些事情,不要先寫代碼,特別是如果你是初學(xué)者,請按照以下步驟操作:
寫下你想要發(fā)生的事
將問題詳細(xì)化為小步驟
寫出分支時(shí)的所有場景和案例
寫入輸入和輸出(方法/函數(shù)簽名)
檢查它們是否適合彼此
讓我們按照這些步驟...
寫下你想要發(fā)生的事
你已經(jīng)很好地定義了你的問題,所以我將跳過這一步。
讓我們進(jìn)一步詳細(xì)說明
你有一份乘客名單
你想按年齡對乘客進(jìn)行分組
你想看看哪些是最常見的/哪些乘客最多。
你想按字母順序打印名字
分支出
場景一:一個(gè)組的規(guī)模比其他所有組都大。
情況二:兩個(gè)或多個(gè)組具有相同的大小并且比其他組大。
可能會有更多的場景,但它們是你的
輸入輸出 ??
現(xiàn)在我們已經(jīng)知道我們必須做什么,我們將檢查每個(gè)步驟的輸入和輸出以實(shí)現(xiàn)這個(gè)目標(biāo)。
步驟:
你有一份乘客名單
輸入 => 無或文件名(字符串)
輸出=> []乘客
你想按年齡對乘客進(jìn)行分組
input => []Passenger // 乘客列表
output => map[int][]int 或 map[int][]&Passenger // ageGroups
第一種,括號內(nèi)的是全組年齡。
第二種類型是一個(gè)列表,其中包含:
乘客在列表中的位置
物體/乘客在內(nèi)存中的地址
這并不重要,只要我們可以輕松地從列表中取回乘客而無需再次迭代即可。
你想看看哪些是最常見的/哪些乘客最多。
輸入 => 組(年齡組)
所以這里我們有場景 1 和場景 2 的分支......這意味著它必須對所有場景都有效或使用條件將它們分支出來。
場景 1 的輸出 => 最常見的年齡 (int)
場景 2 的輸出 => 最常見的年齡 ([]int)
我們可以看到場景 1 的輸出可以與場景 2 的輸出合并
您想要按年齡組中所有乘客的字母順序打印姓名
老實(shí)說,如果你愿意,你可以跳過這個(gè)。
input => groups ([]Passenger) + ages ([]int) + passenger list ([]Passenger).
output => string or []byte or nothing if you just print it...
檢查后,是時(shí)候編碼了
讓我們首先創(chuàng)建適合我們簽名的功能
type Passenger struct {
Name string `json:"name"`
Age int `json:"age"`
}
func GetPassengerList() []Passenger{
// 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 passengers []Passenger
err2 := json.Unmarshal(content, &passengers)
if err2 != nil {
fmt.Println("Error JSON Unmarshalling")
fmt.Println(err2.Error())
}
return passengers
}
// 4a. Group by Age
func GroupByAge(passengers []Passenger) map[int][]int {
group := make(map[int][]int, 0)
for index, passenger := range passengers {
ageGroup := group[passenger.Age]
ageGroup = append(ageGroup, index)
group[passenger.Age] = ageGroup
}
return group
}
// 4b. find the most frequent age numbers
func FindMostCommonAge(ageGroups map[int][]int) []int {
mostFrequentAges := make([]int, 0)
biggestGroupSize := 0
// find most frequent age numbers
for age, ageGroup := range ageGroups {
// is most frequent age
if biggestGroupSize < len(ageGroup) {
biggestGroupSize = len(ageGroup)
mostFrequentAges = []int{age}
} else if biggestGroupSize == len(ageGroup) { // is one of the most frequent age
mostFrequentAges = append(mostFrequentAges, age)
}
// is not one of the most frequent age so does nothing
}
return mostFrequentAges
}
func main() {
passengers := loadPassengers()
// I am lazy but if you want you could sort the
// smaller slice before printing to increase performance
sort.Slice(passengers, func(i, j int) bool {
if passengers[i].Age == passengers[j].Age {
return passengers[i].Name < passengers[j].Name
}
return passengers[i].Age < passengers[j].Age
})
// age => []position
// Length of the array count as the number of occurences
ageGrouper := GroupByAge(passengers)
mostFrequentAges := FindMostCommonAge(ageGrouper)
// print the passenger
for _, age := range mostFrequentAges {
fmt.Println("{")
for _, passengerIndex := range ageGrouper[age] {
fmt.Println("\t", passengers[passengerIndex].Name)
}
fmt.Println("}")
}
}

TA貢獻(xiàn)1877條經(jīng)驗(yàn) 獲得超1個(gè)贊
應(yīng)該比任何更復(fù)雜
按年齡和名稱對源切片進(jìn)行排序
將其分解成具有共同年齡的序列,并且
在進(jìn)行過程中,跟蹤最常見的
是這樣的:
https://goplay.tools/snippet/6pCpkTEaDXN
type Person struct {
Age int
Name string
}
func MostCommonAge(persons []Person) (mostCommonAge int, names []string) {
sorted := make([]Person, len(persons))
copy(sorted, persons)
// sort the slice by age and then by name
sort.Slice(sorted, func(x, y int) bool {
left, right := sorted[x], sorted[y]
switch {
case left.Age < right.Age:
return true
case left.Age > right.Age:
return false
default:
return left.Name < right.Name
}
})
updateMostCommonAge := func(seq []Person) (int, []string) {
if len(seq) > len(names) {
buf := make([]string, len(seq))
for i := 0; i < len(seq); i++ {
buf[i] = seq[i].Name
}
mostCommonAge = seq[0].Age
names = buf
}
return mostCommonAge, names
}
for lo, hi := 0, 0; lo < len(sorted); lo = hi {
for hi = lo; hi < len(sorted) && sorted[lo].Age == sorted[hi].Age; {
hi++
}
mostCommonAge, names = updateMostCommonAge(sorted[lo:hi])
}
return mostCommonAge, names
}
另一種方法使用更多內(nèi)存,但更簡單一些。在這里,我們按年齡構(gòu)建了一個(gè)名字映射,然后對其進(jìn)行迭代以找到具有最長名字列表的鍵。
https://goplay.tools/snippet/_zmMys516IM
type Person struct {
Age int
Name string
}
func MostCommonAge(persons []Person) (mostCommonAge int, names []string) {
namesByAge := map[int][]string{}
for _, p := range persons {
value, found := namesByAge[p.Age]
if !found {
value = []string{}
}
namesByAge[p.Age] = append(value, p.Name)
}
for age, nameList := range namesByAge {
if len(nameList) > len(names) {
mostCommonAge, names = age, nameList
}
}
return mostCommonAge, names
}
- 2 回答
- 0 關(guān)注
- 114 瀏覽
添加回答
舉報(bào)