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

實現倉庫

點這裏

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章