Algorithm 在Matlab中求两个数组结构的交集

Algorithm 在Matlab中求两个数组结构的交集,algorithm,matlab,Algorithm,Matlab,如何在Matlab中找到以下两个数组结构的交集 例如,我有两个结构数组a和b: a(1)=struct('x',1,'y',1); a(2)=struct('x',3,'y',2); a(3)=struct('x',4,'y',3); a(4)=struct('x',5,'y',4); a(5)=struct('x',1,'y',5); b(1)=struct('x',1,'y',1); b(2)=struct('x',3,'y',5); 我想找到a和b的交点,如下所示: c = inte

如何在Matlab中找到以下两个数组结构的交集

例如,我有两个结构数组
a
b

a(1)=struct('x',1,'y',1);
a(2)=struct('x',3,'y',2);
a(3)=struct('x',4,'y',3);
a(4)=struct('x',5,'y',4);
a(5)=struct('x',1,'y',5);


b(1)=struct('x',1,'y',1);
b(2)=struct('x',3,'y',5);
我想找到
a
b
的交点,如下所示:

c = intersect(a,b)
其中
c
应为

c = struct('x',1,'y',1);

但是当我键入
intersect(a,b)
时似乎是错误的,因为
a
b
的元素都是结构。我怎样才能克服这个困难。谢谢。

优雅的解决方案是为
intersect
提供一个比较器操作符(例如,在中)。
不幸的是,Matlab似乎不支持这种功能/灵活性

解决您的问题的方法是

% convert structs into matrices
A = [[a(:).x];[a(:).y]]';
B = [[b(:).x];[b(:).y]]';
% intersect the equivalent representation
[C, ia, ib] = intersect( A, B, 'rows' );
% map back to original structs
c = a(ia);

或者,您是否考虑过用从handle类派生的类对象替换结构?可能会使类的属性过载,然后应该可以直接对类对象进行排序(我还没有仔细研究过这个解决方案-这只是我头脑中的一个建议)。

Shai方法的一个更通用的变体是:

A = cell2mat(permute(struct2cell(a), [3 1 2]));
B = cell2mat(permute(struct2cell(b), [3 1 2]));
[C, ia] = intersect(A, B, 'rows');
c = a(ia);
这样,您就不需要显式指定所有结构字段。当然,如果struct字段包含非数值,这将不起作用

任意类型和维数域的广义方法 如果您不确定存储在结构中的数据的类型和大小,
interest
不会剪切它。相反,您必须对循环使用
isequal
。我在这里使用的是
arrayfun
的优雅:

[X, Y] = meshgrid(1:numel(a), 1:numel(b));
c = a(any(arrayfun(@(m, n)isequal(a(m), b(n)), X, Y)));

一种系统方法是生成一个-然后使用intersect:

hash_fun = @(x) sprintf('x:%g;y:%g',x.x,x.y);

ha = arrayfun(hash_fun,a,'UniformOutput',false);
hb = arrayfun(hash_fun,b,'UniformOutput',false);

[hi,ind_a,ind_b]=intersect(ha,hb)
res=a(ind_a) % result of intersection

只有当所有字段都是数值标量时,solutino才有效。@Shai numeric,是的,但不一定是标量(只要
cell2mat
成功)。这是我目前能做的最好的了。如果它们不是标量,那么它们的大小必须相同。总之,+1表示泛化。@Shai我用
isequal
:)进一步泛化了。哦,我没有意识到。我忽略了哈希函数的什么标准?它应该有一个固定的长度。啊-我明白了。所以一个
%16g
而不是%g将使其成为散列。从技术上说是的。但是这个想法和Shai的答案没有什么不同——只是没有将字段转换成数值向量,而是将它们转换成字符串(字符数组)。在这两种实现中,仍然需要逐个手动指定字段的名称。此外,当字段包含矩阵而不是标量时,当前实现也会失败。我链接的哈希代码生成器可以使用双数组。所以我就用这个函数。