在 julia 中,我们可以检查一个数组是否包含一个值,如下所示:
> 6 in [4,6,5]
true
但是,当尝试以特定顺序检查子数组时,这将返回 false:
> [4,6] in [4,6,5]
false
验证数组中是否存在特定子数组的正确语法是什么?
我认为值得一提的是,在 Julia 1.0 中你有这个功能issubset
> issubset([4,6], [4,6,5])
true
您也可以使用\subseteq
乳胶符号非常方便地调用它
> [4,6] ⊆ [4,6,5]
true
这对我来说看起来很优化:
> using Random
> x, y = randperm(10^3)[1:10^2], randperm(10^3);
> @btime issubset(x, y);
16.153 μs (12 allocations: 45.96 KiB)
编写一个性能良好的函数需要一点代码,但这比issubvec
上面的版本快得多:
function subset2(x,y)
lenx = length(x)
first = x[1]
if lenx == 1
return findnext(y, first, 1) != 0
end
leny = length(y)
lim = length(y) - length(x) + 1
cur = 1
while (cur = findnext(y, first, cur)) != 0
cur > lim && break
beg = cur
@inbounds for i = 2:lenx
y[beg += 1] != x[i] && (beg = 0 ; break)
end
beg != 0 && return true
cur += 1
end
false
end
注意:如果该函数实际上返回子数组的开始位置(如果找到),或者如果没有返回 0,这也将更加有用,类似于 findfirst/findnext 函数。
时序信息(第二个是使用我的subset2函数):
0.005273 seconds (65.70 k allocations: 4.073 MB)
0.000086 seconds (4 allocations: 160 bytes)
对于第三个条件,即向量显示为以下函数[4,6]
的子向量,建议:4,6,5
issubvec(v,big) =
any([v == slice(big,i:(i+length(v)-1)) for i=1:(length(big)-length(v)+1)])
对于第二个条件,即为els
vector中出现的set
vector中的每个元素给出一个布尔值,建议如下:
function vecin(els,set)
res = zeros(Bool,size(els))
res[findin(els,set)]=true
res
end
使用 OP 中的向量,这些结果为:
julia> vecin([4,6],[4,6,5])
2-element Array{Bool,1}:
true
true
julia> issubvec([4,6],[4,6,5])
true
请注意,您现在可以in
使用点进行矢量化:
julia> in([4,6,5]).([4, 6])
2-element BitArray{1}:
true
true
并链接all
以获得您的答案:
julia> all(in([4,6,5]).([4, 6]))
true
我最近用它来查找整数数组中的子序列。它不如@scott 的好或快subset2(x,y)
......但它返回索引。
function findsequence(arr::Array{Int64}, seq::Array{Int64})
indices = Int64[]
i = 1
n = length(seq)
if n == 1
while true
occurrence = findnext(arr, seq[1], i)
if occurrence == 0
break
else
push!(indices, occurrence)
i = occurrence +1
end
end
else
while true
occurrence = Base._searchindex(arr, seq, i)
if occurrence == 0
break
else
push!(indices, occurrence)
i = occurrence +1
end
end
end
return indices
end
julia> @time findsequence(rand(1:9, 1000), [2,3])
0.000036 seconds (29 allocations: 8.766 KB)
16-element Array{Int64,1}:
80
118
138
158
234
243
409
470
539
589
619
629
645
666
762
856