代码背景
vldb summer school 22中写lab0作业过程中遇到了一个可以提升的点在于从一个长数组中获取前k名组成的数组。下面进行形式化定义:
A
=
[
a
1
,
a
2
,
a
3
,
a
4
.
.
.
a
n
]
,
a
1
,
a
2
,
.
.
.
a
n
∈
N
A = [a_1, a_2, a_3, a_4...a_n], a_1, a_2,... a_n \in N
A=[a1,a2,a3,a4...an],a1,a2,...an∈N 找到可以得到topk数组的函数,其中
t
o
p
k
=
[
a
m
a
x
1
,
a
m
a
x
2
,
.
.
.
a
m
a
x
k
]
topk = [a_{max1}, a_{max2}, ...a_{maxk}]
topk=[amax1,amax2,...amaxk]
代码用go语言实现。
代码思路
遍历A,对于A中任意元素进行判断:
- 当此时获得的topk数组长度不足k时,即把元素插入到topk合适位置
- 当此时获得的topk数组长度等于k时,即先判断元素是否大于topk中最小元素,如果大于最小元素,即可以先将最小元素从topk中排出去,然后将新元素插入到合适位置中。
最终代码正文中实现了
func minimum(list []int) int // get the minimum num in a list
func pushright(list []int, new int) []int // put the new int into the right place in a list
func popmin(list []int) []int // pop the minimum int of a int list
func getTopK(list []int, k int) []int // get topk item of a int list
代码实现
package main
import (
"fmt"
"os"
"strconv"
)
// a long list A[] = [1,3,2,...], we try to find the top k value in the A[] and return the top k
const INT_MAX = 127
func minimum(list []int) int { // get the minimum num in a list
min := INT_MAX
for _, i := range list {
if i < min {
min = i
}
}
return min
}
func pushright(list []int, new int) []int { // put the new int into the right place in a list
var lengthOflist = len(list)
if lengthOflist == 0 {
list = append(list, new)
return list
} else {
list = append(list, new)
for p := 0; p < lengthOflist; p++ {
if new > list[p] {
flag := p
// fmt.Println("flag: ", flag, lengthOflist)
for ptmp := lengthOflist; ptmp > flag; ptmp-- {
// fmt.Println(ptmp, ptmp-1)
list[ptmp] = list[ptmp-1]
}
list[flag] = new
break
return list
}
}
}
return list
}
func popmin(list []int) []int { // pop the minimum int of a int list
var min = minimum(list)
for p, i := range list {
if i == min {
for tmpp := p; tmpp+1 < len(list); tmpp++ {
list[tmpp] = list[tmpp+1]
}
}
}
return list[:len(list)-1]
}
func getTopK(list []int, k int) []int { // get topk item of a int list
topk := make([]int, 0)
var lengthOftopK = 0
for _, i := range list {
// fmt.Println(i, lengthOftopK)
if lengthOftopK < k {
// topk = append(topk, i)
topk = pushright(topk, i)
lengthOftopK += 1
} else if lengthOftopK == k {
if i > minimum(topk) {
// fmt.Println(" i > mini")
topk = popmin(topk)
topk = pushright(topk, i)
// topk = append(topk, i)
}
} else {
fmt.Println("The length of topK should not be bigger than K")
}
// fmt.Println(topk)
}
return topk
}
func main() {
var A = []int{1000, 2, 3, 7, 50, 9}
var k, err = strconv.Atoi(os.Args[1])
if err != nil {
fmt.Println("Atoi error in main")
}
var topk = getTopK(A, k)
fmt.Println("the min of A is: ", minimum(A))
fmt.Println(topk)
}