Golang如何减少给定数据中for循环的使用并实现返回众数的函数
Golang如何减少给定数据中for循环的使用并实现返回众数的函数 以下是给定链接中返回数据集中众数的程序。
https://play.golang.org/p/rgZJhJ-gtY7
有没有办法进一步优化它?
“我这样做是为了练习用 Golang 进行数据科学。”
func main() {
fmt.Println("hello world")
}
2 回复
第二个循环可以合并到第一个循环中。
package main
import "fmt"
type data []float64
func main() {
numFriends := []float64{100.0, 49, 41, 40, 25, 21, 21, 19, 19, 18, 18, 16, 15, 15, 15, 15, 14, 14, 13, 13, 13, 13, 12, 12, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
var mode []float64
m := make(map[float64]int)
// entering data to a map and creating counter
var maxFreq int
for _, i := range numFriends {
m[i]++
if m[i] > maxFreq {
maxFreq = m[i]
}
}
// getting the mode on the basis of max value in the map
for i, _ := range m {
if maxFreq == m[i] {
mode = append(mode, i)
}
}
fmt.Println(mode)
}
更多关于Golang如何减少给定数据中for循环的使用并实现返回众数的函数的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中减少for循环使用并高效计算众数,可以通过使用map进行频率统计,然后一次遍历找出最大频率值。以下是优化后的实现:
package main
import (
"fmt"
)
// Mode 返回int切片的众数(出现次数最多的元素)
// 如果有多个众数,返回第一个遇到的
func Mode(data []int) int {
if len(data) == 0 {
return 0
}
frequency := make(map[int]int)
maxCount := 0
mode := data[0]
for _, value := range data {
frequency[value]++
if frequency[value] > maxCount {
maxCount = frequency[value]
mode = value
}
}
return mode
}
func main() {
// 测试用例
testData := []int{1, 2, 2, 3, 3, 3, 4, 4, 4, 4}
fmt.Printf("数据集: %v\n", testData)
fmt.Printf("众数: %d\n", Mode(testData))
// 另一个测试
testData2 := []int{5, 5, 2, 2, 2, 7, 7, 7, 7, 8}
fmt.Printf("\n数据集: %v\n", testData2)
fmt.Printf("众数: %d\n", Mode(testData2))
}
如果希望返回所有众数(当有多个值出现次数相同时),可以使用以下版本:
func ModeAll(data []int) []int {
if len(data) == 0 {
return []int{}
}
frequency := make(map[int]int)
maxCount := 0
// 第一次遍历:统计频率并找出最大出现次数
for _, value := range data {
frequency[value]++
if frequency[value] > maxCount {
maxCount = frequency[value]
}
}
// 第二次遍历:收集所有出现次数等于maxCount的值
modes := make([]int, 0)
for value, count := range frequency {
if count == maxCount {
modes = append(modes, value)
}
}
return modes
}
func main() {
// 测试多个众数的情况
testData := []int{1, 2, 2, 3, 3, 3, 4, 4, 4}
fmt.Printf("数据集: %v\n", testData)
fmt.Printf("所有众数: %v\n", ModeAll(testData))
}
对于大型数据集,可以使用并行处理进一步优化:
import (
"fmt"
"sync"
)
func ModeParallel(data []int) int {
if len(data) == 0 {
return 0
}
var mu sync.Mutex
frequency := make(map[int]int)
maxCount := 0
mode := data[0]
var wg sync.WaitGroup
chunkSize := len(data) / 4 // 分成4个goroutine处理
for i := 0; i < 4; i++ {
wg.Add(1)
start := i * chunkSize
end := start + chunkSize
if i == 3 {
end = len(data)
}
go func(slice []int) {
defer wg.Done()
localFreq := make(map[int]int)
for _, value := range slice {
localFreq[value]++
}
mu.Lock()
for value, count := range localFreq {
frequency[value] += count
if frequency[value] > maxCount {
maxCount = frequency[value]
mode = value
}
}
mu.Unlock()
}(data[start:end])
}
wg.Wait()
return mode
}
这些实现通过减少循环次数和使用合适的数据结构,提高了计算众数的效率。第一个版本只需要一次遍历即可找到众数,时间复杂度为O(n)。

