如何从一个数组中删除另一个数组的元素?

4

我有两个数组:

A=[1 1 2 2 3 3 3];
B=[1 3];

有没有一种函数可以从A中删除包含在B中的元素?
结果应该是:
C=[1 2 2 3 3];

顺序不重要,但是如果在 A 中出现了更具体的元素(例如两次出现的 1),则需要执行操作,仅删除与 B 中相同数量的这些特定元素(在本例中只有一个 1 和一个 3;这意味着其他 13 应该保留在最终产品 C 中)。此函数类似于 setdiff,但不同之处在于它应该处理数组元素的多个实例。这种类比是因为我的 B 只包含在 A 中存在的元素。

2个回答

4

使用for循环的解决方案:

C = A;    
for ii = 1:length(B)       
   C(find(C == B(ii), 1,'first')) = [];
end

结果

C =

     1     2     2     3     3

谢谢。我必须记住这个。但是在查找中的那个 A 必须是一个 C,否则你会删除错误的元素。例如,尝试使用 A=[1 1 2 2 3 4 4];,如果在查找中有一个 A,你最终会删除一个 4 而不是一个 3 - Dan

1
这是一个使用accumarrayrepelem的向量化解决方案:
maxValue = max([A B]);
counts = accumarray(A(:), 1, [maxValue 1])-accumarray(B(:), 1, [maxValue 1]);
C = repelem(1:maxValue, max(counts, 0));

以下是您的样本数据 A = [1 1 2 2 3 3 3]; B = [1 3]; 的结果:

C =

     1     2     2     3     3

这甚至适用于 B 中有而 A 中没有的值的情况(例如 B = [1 4];)或者 B 中某个值比 A 中出现次数更多的情况(例如 B = [1 1 1];)。

注意:上述方法适用于 AB 都包含整数的情况。如果它们包含浮点数值,你可以首先使用 uniqueismember 将唯一值映射为整数。假设我们有以下样本数据:

A = [0 0 pi pi 2*pi 2*pi 2*pi];
B = [0 2*pi];

这是上述代码的一个变体,可以处理这种情况:
uniqueValues = unique([A B]);
[~, A] = ismember(A, uniqueValues);
[~, B] = ismember(B, uniqueValues);
maxValue = max([A B]);
counts = accumarray(A(:), 1, [maxValue 1])-accumarray(B(:), 1, [maxValue 1]);
C = uniqueValues(repelem(1:maxValue, max(counts, 0)));

并且结果是:

C =

         0    3.1416    3.1416    6.2832    6.2832  % [0 pi pi 2*pi 2*pi]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接