5.集合运算
集合是指具有某种特定性质的具体的或抽象的对象汇总而成的集体。其中,构成集合的这些对象则称为该集合的元素。集合中的元素具有三个性质:确定性(给定一个集合,任给一个元素,都可以确定该元素是否属于该集合)、互异性(任何两个元素都是不相同的)和无序性(每个元素的地位都是相同的,元素之间是没有顺序的)。
(1)unique函数
unique函数可用来提取数组中的唯一值,它可以用在我们学过的向量和矩阵上,也可以用在我们未来章节要学的表格上。matlab官网上的介绍如下图所示:
A = [5 -6 5 10 8 -6 -3 -3]
A1 = unique(A) %对A去重并排序
A2 = unique(A,'stable') %对A去重不排序
B = [1:5,3:-1:1]
B2 = unique(B)
C = [5;1;3;1;3;5;3]
C1 = unique(C)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
A = [5 -6 5 10 8 -6 -3 -3] %ia是C中的每个元素在A中的索引值
% ic是A中的每个元素在C中的索引值
[C,ia,ic] = unique(A) %C = A(ia)
%如果A是一个矩阵,那么unique(A)的结果和unique(A(:))的结果相同。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
A = [3 5
6 8
3 5
4 1
2 8
2 5
4 1]
A1 = unique(A)
A2 = unique(A(:)) %A1和A2相等
A3 = unique(A,'rows') %将A的每一行视为一个整体,会返回A中的唯一行
A4 = unique(A,'rows','stable') %不排序
[C,id1,id2] = unique(A) % 返回的索引是线性索引
[C,id1,id2] = unique(A,'rows') % 返回的索引是行索引
(2)ismember函数
h = ismember(A,B)可以判断数组A中的元素是否在数组B内,h是和A同等大小的逻辑数组,为逻辑1时说明该位置的A元素在B中存在,为逻辑0时说明在B中不存在。
ismember可以有两个返回值:[h, ib] = ismember(A,B)
h就是上面的那个逻辑数组。
ib是和A大小相同的一个数组,对于 A 中属于 B 的成员的每一个值,ib 会包含该值在 B 中的最小索引;如果值为 0 表示 A 不是 B 的成员。
如果B和A的列数相同,那么我们可以加一个输入参数'rows',这时候ismember(A, B, 'rows')会将A的每一行视为一个整体,然后在B中查找。
A = [4 1 3 4 8];
B = [3 7 4 5 4 9 6];
h = ismember(A,B)
h2 = ismember(B,A)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
A = [3,1;
8,5;
4,0];
B = [3 7 4 5 4 9 6];
h = ismember(A,B)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
A = [3,1;
8,5;
4,0];
B = [3 7 4 5;
1 4 9 6];
h = ismember(A,B)
h2 = ismember(B,A)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
A = [4 1 3 4 8];
B = [3 7 5 4 9 6];
[h,ib] = ismember(A,B)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
A = [6 8;
3 5;
4 1];
B = [1 2
3 5
3 8
6 1];
[h,ib] = ismember(A,B,"rows")
%已知某彩票由三个数组成(有顺序),每个数都是1-10上的整数
% 如果玩家买的三个数字和开奖号码的三个数字完全相同(包括顺序),则中了一等奖;
% 如果有任意两个数字相同(包括顺序),则中了二等奖。
% 其他情况则都不算中奖。
% 例如开奖号码是5 3 7,玩家号码是5 6 7、4 3 7都中了二等奖;3 5 7 则不中奖,因为顺序不同。
% 现在请你模拟以下情形:
% 某玩家买了100张彩票,彩票票面数字都是随机生成的。
% 已知今天的开奖号码是8,3,5,请判断是否中了一等奖和二等奖,若中了请返回中奖的彩票数字和对应的索引。
n = 1000;
A = randi([1,10],n,3);
kjh = [8,3,5]
ydj = ismember(A,kjh,"rows");
haoma1 = find(ydj);
edj1 = ismember(A(:,[1,2]),kjh([1,2]),"rows") & (A(:,3) ~= kjh(3));
edj2 = ismember(A(:,[1,3]),kjh([1,3]),"rows") & (A(:,2) ~= kjh(2));
edj3 = ismember(A(:,[2,3]),kjh([2,3]),"rows") & (A(:,1) ~= kjh(1));
edj4 = ismember(A(:,[1,2]),kjh([1,3]),"rows") & (A(:,3) ~= kjh(2));
edj5 = ismember(A(:,[1,2]),kjh([2,3]),"rows") & (A(:,3) ~= kjh(1));
edj6 = ismember(A(:,[1,3]),kjh([1,2]),"rows") & (A(:,2) ~= kjh(3));
edj7 = ismember(A(:,[1,3]),kjh([2,3]),"rows") & (A(:,2) ~= kjh(1));
edj8 = ismember(A(:,[2,3]),kjh([1,2]),"rows") & (A(:,1) ~= kjh(3));
edj9 = ismember(A(:,[2,3]),kjh([1,3]),"rows") & (A(:,1) ~= kjh(2));
haoma2 = find(edj1|edj2|edj3|edj4|edj5|edj6|edj7|edj8|edj9)
%不考虑顺序版本
A1 = sort(A,2)
ydj_ = ismember(A(:,[1,2,3]),kjh(1,2,3),"rows")
haoma1_ = find(ydj_)
edj_ = ismember(A(:,[1,2]),kjh(1,2),"rows")
haoma2_ = find(edj_)
(3)intersect、union、setdiff和setxor函数
这四个函数分别用于计算两个数组之间的交集、并集、差集和对称差集,下面给出了这四个函数对应的维恩图。
因为这四个函数的用法类似,所以我们下面主要以intersect函数为例,介绍它们的用法。
C = intersect(A,B)会返回数组A和B的共同数据,但是不包含重复项,返回的C默认会排序。
如果A和B的列数相同,那么我们可以加一个输入参数'rows',这时候intersect (A, B, 'rows')会将A和B的每一行视为一个整体,然后找到公共的行。
intersect函数可以有最多三个返回值,[C,ia,ib] = intersect(___) 还使用上述任何语法返回索引向量 ia 和 ib。
- 一般情况下,C = A(ia) 且 C = B(ib)。
- 如果指定了 'rows' 选项,则 C = A(ia,:) 且 C = B(ib,:)。
A = [5 3 1 4 2 7 2];
B = [2 8 6 1 0 3 9 5];
C = intersect(A,B)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
A = [1 2 4;
3 4 8];
B = [1 3;
8 7;
1 2];
C = intersect(A,B,"stable") %会按照在A中出现的顺序返回C中的值。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
A = [3 3 3;
0 0 1;
1 0 3;
1 1 1];
B = [1 0 3;
3 3 3;
0 0 0];
C = intersect(A,B,"rows")
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
A = [5 3 1 4 2 7 2];
B = [2 8 6 1 0 3 9 5];
[C,ia,ib] = intersect(A,B) %ia是交集C在A中的线性索引ib是交集C在B中的线性索引
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
A = [3 3 3;
0 0 1;
1 0 3;
1 1 1];
B = [1 0 3;
3 3 3;
0 0 0];
[C,ia,ib] = intersect(A,B,'rows')
其他三个函数的用法简单举的例子:
A = [5 3 1 7 2];
B = [2 8 6 1 5];
C = union(A,B,"stable") %并集
D = setdiff(A,B,"stable") %A中存在B中不存在
E = setxor(A,B,"stable") %A,B的对称差集
A1 = [6 3;
5 1;
3 7];
B1 = [4 2;
5,1]
C1 = union(A1,B1,'rows')
D1 = setdiff(A1,B1,"rows")
E1 = setxor(A1,B1,"rows")
参考:数学建模清风老师《MATLAB教程新手入门篇》https://www.bilibili.com/video/BV1dN4y1Q7Kt/