我需要找到向量中比之后的一个或多个元素小的元素。使用循环非常容易实现:
x = some_vector_values;
for m = 1 : length(x)
if( any( x(m+1:end) > x(m) )
do_such_and_such;
end
end
但速度让我抓狂。我正在想尽一切办法来寻找高效的解决方案,但却束手无策。数组长度可能达到数千,并且我需要为许多不同的数组执行此操作。
我需要找到向量中比之后的一个或多个元素小的元素。使用循环非常容易实现:
x = some_vector_values;
for m = 1 : length(x)
if( any( x(m+1:end) > x(m) )
do_such_and_such;
end
end
但速度让我抓狂。我正在想尽一切办法来寻找高效的解决方案,但却束手无策。数组长度可能达到数千,并且我需要为许多不同的数组执行此操作。
true
和被拒绝元素的false
的逻辑向量ind
。最终结果将是x(ind)
。x = [3 4 3 5 6 3 4 1];
n = numel(x);
ind = false(1,n); %// intiallization
s = 1; %// starting index of the part of x that remains to be analyzed
while s <= n %// if s > n we have finished
[~, m] = max(x(s:end)); %// index of maximum within remaining part of x
ind(s:s-2+m) = true; %// elements to its left are accepted
s = s+m; %// update start of remaining part
end
通过将 while
条件更改为 while s < n
,可以稍微减少运行时间,因为最后一个元素总是被拒绝。
O(n log(n))
,而不是O(log(n))
。我认为我的解决方案是O(n)
。 - Bas Swinckelsmax
会引入一个线性因素。已更正。 - Luis MendoO(n)
,但是在最坏情况下(当x严格递减时),为O(n^2)
。 - Bas Swinckels一句话版本
comparisons = any(triu(bsxfun(@gt,x(:).',x(:))),2)
numel(x)=10000
),这种解决方案速度较慢。 - Danielbsxfun
时进行了拉伸,正如 @natan 指出的那样。 - Divakarx
的维度(即输入 x(:)
)或进行检查。 - chappjcif any(...)
在第一次迭代时必须检查n
个项目,然后在第二次迭代中检查n-1
个项目......直到在最后一次迭代中检查单个项目。因此,总体上它需要大约n^2/2
次比较,因此它的运行时间是输入向量长度的平方函数!x
进行比较(未经测试):% calculate vector mx for which mx(i) = max(x(i:end))
mx = zeros(size(x));
mx(end) = x(end);
for i = length(x)-1:-1:1 % iterate backwards
mx(i) = max(x(i), mx(i+1));
end
for i = 1:length(x) - 1
if mx(i) > x(i)
do_such_and_such(i);
end
end
如果您不关心执行do_such_and_such
的顺序,这些for循环甚至可以像这样组合:
mx = x(end);
for i = length(x)-1:-1:1 % iterate backwards
if x(i) < mx
do_such_and_such(i);
end
mx = max(x(i), mx); % maximum of x(i:end)
end
x = some_values'; % x should be a column vector to use this
h = hankel(x);
m = max(h,[],2);
f = find(x<m) %returns indices or f = (a<m) %returns true/false
然后,您可以使用索引或true/false来迭代通过for循环并执行一些操作。以下是一个例子:x =
9
8
16
16
4
10
9
13
15
1
>> h = hankel(x)
h =
9 8 16 16 4 10 9 13 15 1
8 16 16 4 10 9 13 15 1 0
16 16 4 10 9 13 15 1 0 0
16 4 10 9 13 15 1 0 0 0
4 10 9 13 15 1 0 0 0 0
10 9 13 15 1 0 0 0 0 0
9 13 15 1 0 0 0 0 0 0
13 15 1 0 0 0 0 0 0 0
15 1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
>> m = max(h,[],2)
m =
16
16
16
16
15
15
15
15
15
1
>> f = find(a<m)
f =
1
2
5
6
7
8
O(n^2)
内存。 - Bas Swinckels@NKN说得对。排序。
x = some_vector_values;
[Y,I]=sort(x); %sort in order, get indices
dy=gradient(Y); %get difference vector same size as input vector
ind=find(dy~=0);%ignore places that are equal to the value of interest
for m = 1 : length(ind)
do_such_and_such to Y(ind(m));
end
祝你好运
sort
函数还可以返回排序后元素的原始索引。 - dustincarrif
比较。 - AnonSubmitter85