MATLAB - 循环大小变量数组?

时间:2014-06-27 23:25:24

标签: matlab

我有一个数组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。:这是我的问题的简化版本,实际上涉及更多。所以请不要颠覆性地修改算法。

2 个答案:

答案 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