我有一个数组a
和一个new_elem
。
new_elem
小于a
中的任何现有成员,则不允许将其添加到a
。new_elem
大于a
中的任何现有成员,则可以将其添加到a
,和小于new_elem
的元素必须被踢出。我按如下方式实现了这个。
a = [a new_elem]; % add in first
for idx = 1:1:numel(a)-1
% new_elem < some existing member
if a(idx) > new_elem
a = a(1:end-1); % kick new_elem out
break;
% new_elem > some existing member
elseif a(idx) < new_elem
a(a==a(idx)) = []; % kick that exisiting member out
end
end
当new_elem
较小时,该代码段有效,例如,
new_elem = 4;
a = [5 5 5 5 5];
失败,错误为 Index exceeds matrix dimensions.
在其他情况下,例如,
new_elem = 6;
a = [5 5 5 5 5];
我理解问题是,一旦我们踢出现有元素,a
的大小发生变化,因此,我们将无法索引最终元素,因为numel(a)
已经在循环开始。
我该如何解决?
P.S。:这是我的问题的简化版本,实际上涉及更多。所以请不要颠覆性地修改算法。
答案 0 :(得分:1)
为什么不在a
中获取小于new_elem
的所有元素的列表/数组,并根据它做出决定,完全避免循环?
% get a list of all indices of elements in a that are less than new_elem
minIdcs = find(a<new_elem);
% if the length of this list is less than the length of a, then there is at
% least one element in a that is greater than new_elem - so only add new_elem
% if the lengths are identical
if length(minIdcs) == length(a)
% remove all elements of a that are less than new_elem
a(minIdcs) = [];
% now add new_elem to a
a = [a new_elem];
end
这有效,但我不确定它是否与您的意图兼容,因为您的代码依赖于a
中元素的顺序:new_elem
可能小于a
中的至少一个元素{1}},但是循环的多次迭代可能不会遇到该元素,因此在我们做出不应添加a
的决定之前,可能会删除new_elem
的其他元素。
如果订单很重要,那么您可以使用while
循环
a = [a new_elem]; % add in first
idx = 1;
n = length(a);
while idx < n
% new_elem < some existing member
if a(idx) > new_elem
a = a(1:end-1); % kick new_elem out
break;
% new_elem > some existing member
elseif a(idx) < new_elem
a(idx) = []; % kick that exisiting member out
n = n-1;
else
idx=idx+1;
end
end
以上内容与您的内容非常相似 - 我们只需要跟踪列表中的元素数量(每当我们删除元素时都会调整),我们只需要增加索引idx
当我们不删除元素时。而不是一次性删除所有小于new_elem
的元素,我们会根据具体情况处理它们(所以a(idx) = [];
而不是a(a==a(idx)) = [];
)。
答案 1 :(得分:0)
这个简单的代码应该做你想做的事情:
if new_elem > min(a)
a = [new_elem a(find(new_elem < a))]
end