golang算法-计算10000个数里最小的10个数

前言

从包含M个数字的池子里,取出前k个(最小的)数字。

分析

使用mapreduce思想,将M个数字的池,拆成容量为vol的子池,对子池取出最小的10个数,将所有子池的最小十个数合并,再取一下最小10个数。

  • 生成M个数字的大数组
func GenMNumberArr(M int, seed time.Time) []int {
	var rs = make([]int, 0, M)
	rand.Seed(seed.UnixNano())
	for i := 0; i < M; i++ {
		rs = append(rs, rand.Intn(1029381))
	}
	return rs
}

// 生成了长度20的随机数组
// 输出[...], 20
func TestGenMNumberArr(t *testing.T) {
	rs := GenMNumberArr(20, time.Now())
	fmt.Println(len(rs))
	fmt.Println(rs)
}
  • 子池拆分
func SplitArr(arr []int, vol int) [][]int {
	var rs = make([][]int, 0, 100)
	var tmp []int
L:
	for i, _ := range arr {
		if (i+1)%vol == 0 {
			tmp = arr[0 : i+1]
			rs = append(rs, tmp)
			arr = arr[i+1:]
			goto L
		} else {
			if i == len(arr)-1 {
				rs = append(rs, arr)
			}
			continue
		}
	}
	return rs
}
// 输出 [[1 24 1 2 3] [4 11 12 19 11] [17 19 22 23]]
func TestSplitArr(t *testing.T) {
	rs := SplitArr([]int{1, 24, 1, 2, 3, 4, 11, 12, 19, 11, 17, 19, 22, 23}, 5)
	fmt.Println(rs)
}
  • 对包含大于等于K个数字的数组,进行取最小的十个数字的操作
// 从数组中,选出最小的K个数据,并升序排列成数组
func GetMinK(k int, src []int) []int {
	if k > len(src) {
		panic(fmt.Errorf("min k must smaller than src length, but got k '%d', src.len '%d'", k, len(src)))
	}
	var tmp int
	for i := 0; i < k; i++ {
		for j := i + 1; j < len(src); j++ {
			if src[i] > src[j] {
				tmp = src[i]
				src[i] = src[j]
				src[j] = tmp
			}
		}
	}
	return src[:k]
}

// 从数组中,选取了最小的4个
// 输出 [1 2 3 3] 
func TestGetMinK(t *testing.T) {
	rs := GetMinK(4, []int{1, 3, 4, 5, 6, 12, 3, 2, 15, 199})
	fmt.Println(rs)
}
  • 最后,从10000个数中,取最小的10个数
func TestGetMin10NumberFrom10000(t *testing.T) {
	arr10000 := GenMNumberArr(10000, time.Now())

	subArrs := SplitArr(arr10000, 100)

	minArr := make([]int, 0, 100)
	for i, _ := range subArrs {
		minArr = append(minArr, GetMinK(10, subArrs[i])...)
	}

	rs :=GetMinK(10, minArr)
	fmt.Println(rs)
}
实现仓库

点这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值