function popZero!(a,numZero::Int)
# pop! 0 out of the array for numZero times
# a : An vector
# numZero : how many zero you wannna pop out
b = []
for i = 1:numZero
if a[end] == 0.0
pop!(a)
else
push!(b,pop!(a))
while b[end] !=0.0
push!(b,pop!(a))
end
pop!(b)
while b != []
push!(a,pop!(b))
end
end
end
end
# example
# a = rand(5);
# [a[i]=0 for i in [1,2,3]]
# popZero!(a,2)
1 个赞
动态修改数组大小就快不了。
我可能会 zero 个新数组,然后逐个复制,跳过 0
如果要原地算法,可能原地的自定义排序(0最大)会快点?
我之前翻过lisp语言的《 a little schemer》,里面push和pop这个动作出现在很开篇的地方&我对于计算机的理解是指针经过纸带,因此我认为这两函数非常底层…这个算法在我脑袋里是:好韭菜切段装盆剔除坏韭菜段装回原盆。我的直觉告诉我这非常快,至少相比于“先去一段一段搜索地找到坏韭菜记录坏韭菜位置复制出没有坏韭菜的好韭菜”
function popZero2!(a)
b = iszero.(a)*true
deleteat!(a,b)
end
可以构造几个例子用 BenchmarkTools.jl
的 @btime
测一测。
push!, pop! 是原地操作内存,速度快没问题。但它们会修改数组的大小,容易触发 GC,这就得不偿失了。
如果有实际的案例、问题会更好讨论。
1 个赞