Check for equality in the contents of two arrays ignoring order
65 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Bill Tubbs
am 17 Okt. 2021
Kommentiert: Bill Tubbs
am 18 Okt. 2021
I want to check that the contents of two arrays are equal, ignoring ordering of the elements.
I couldn't find an existing answer on this for some reason. There are two parts to this question, depending on whether the arrays are sets or not.
1. Checking equality for two sets
Assuming there are no duplicates I could use set operaions but it doesn't look like Matlab has sets, only set operations, and I couldn't find a setisequal function. Also, there are so many possible ways to do it I'm not sure which is the best:
A = [1 3]; B = [3 1];
assert(isequal(intersect(A, B), union(A, B)))
or
assert(isempty(setdiff(A,B)) & isempty(setdiff(B,A)))
or
assert(all(ismember(B, A)) & all(ismember(A, B)))
or
assert(isequal(unique(A), unique(B)))
However, if there may be different numbers of duplicates in either of the two arrays, then the above set operations will ignore them.
2. Checking equality for non-sets
This is the best I could think of in this case but it involves two sort operations which is quite inefficient:
assert(isequal(sort(A), sort(B)))
No doubt there is something very simple that I am missing here...
0 Kommentare
Akzeptierte Antwort
Walter Roberson
am 17 Okt. 2021
%sets case
A = [1 3]; B = [3 1];
isequal(unique(A), unique(B))
For the sets case, a different approach just might be faster:
numel(A) == numel(B) && all(ismember(A, B))
%nonset case:
A = [1 3]; B = [3 1 3];
isequal(unique(A), unique(B))
7 Kommentare
Walter Roberson
am 18 Okt. 2021
%implementation #1
0.1 + 0.2 - 0.3
%implementation #2
0.1 - 0.3 + 0.2
Two implementation of the same algorithm involving floating point values will typically not return identical results.
Weitere Antworten (2)
Jan
am 17 Okt. 2021
unique, setdiff, union and ismember call the function sort also internally. So
% assert(isequal(sort(A), sort(B)))
Is a very efficient solution.
A = randperm(1e6, 1e6);
B = randperm(1e6, 1e6);
tic
for k = 1:10
isequal(sort(A), sort(B));
end
toc
tic
for k = 1:10
all(ismembc(A, sort(B))); % Internal helper of ISMEMBER
end
toc
If repeated elements are existing:
A = randi([0,1e3], 1, 1e6);
B = randi([0,1e3], 1, 1e6);
tic
for k = 1:10
isequal(unique(A), unique(B));
end
toc
tic
for k = 1:10
numel(A) == numel(B) && all(ismember(A, B));
end
toc
tic
for k = 1:10
As = sort(A);
Au = As([true, diff(As) ~= 0]); % Remove repeated elements
Bs = sort(B);
Bu = Bs([true, diff(Bs) ~= 0]); % Remove repeated elements
isequal(Au, Bu);
end
toc
In R2018b the last method is faster than isequal(unique(A), unique(B)). Try this locally.
1 Kommentar
Siehe auch
Kategorien
Mehr zu Loops and Conditional Statements finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!