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)。

回到顶部