How to find a vector in a matrix?

3 次查看(过去 30 天)
Hi all, I just wonder whether there are Matlab functions which can deal with the problem. Say,
A=[1 1 1 1; ...
1 1 2 3; ...
1 2 3 1; ...
1 1 1 2];
B=[1 2 3]
So B appears twice in A.
I tried ismember, but it finds all the elements of B in A, regardless of the sequence.
Thanks!
  1 个评论
Shashank Prasanna
Shashank Prasanna 2013-1-16
Just to clarify, you don't want to do this using a for loop? that would be fairly straightforward

请先登录,再进行评论。

采纳的回答

Matt J
Matt J 2013-1-16
A=[1 1 1 1; 1 1 2 3; 1 2 3 1; 1 1 1 2];
B=[1 2 3];
[j,i]=ind2sub(fliplr(size(A)), strfind(reshape(A.',1,[]),B).' );
>> [i,j]
ans =
2 2
3 1

更多回答(5 个)

Andrei Bobrov
Andrei Bobrov 2013-1-17
编辑:Andrei Bobrov 2013-1-17
s = size(B) - 1;
n = size(A) - s;
out = [];
for ii = 1:n(1)
i1 = ii : ii + s(1);
for jj = 1:n(2)
if isequal(A(i1,jj : jj + s(2)),B)
out = [out;[ii,jj]];
end
end
end

José-Luis
José-Luis 2013-1-16
A=[1 1 1 1; 1 1 2 3; 1 2 3 1; 1 1 1 2];
B=[1 2 3];
isSubStr = @(x,y) ~isempty(strfind(x,y));
getStr = @(x) sprintf('%d',x);
numVals = size(A,2);
logical_index = arrayfun(@(idx) isSubStr(getStr(A(idx,:)),getStr(B)),1:numVals)';

Matt J
Matt J 2013-1-16
编辑:Matt J 2013-1-16
N=sqrt( conv2(A.^2,ones(size(B)), 'valid' ));
[i,j]=find(abs( conv2(A,fliplr(B)/norm(B),'valid')./N - 1)<=1e-6)

Roger Stafford
Roger Stafford 2013-1-17
Another way:
[m,n] = size(A);
k = length(B(:));
p = hankel(1:k,k:n);
f = find(all(bsxfun(@eq,reshape(A(:,p).',k,n-k+1,m),B(:)),1));
[c,r] = ind2sub([n-k+1,m],f);
where c gives the column indices and r the row indices in A where a match with B begins. In your example these would be
r c
- -
2 2
3 1

Raymond
Raymond 2013-1-17
Thanks all! All the solutions work, but Matt's looks simpler and more efficient.
I want to avoid for loops since I have to deal with big matrix.
  2 个评论
Sean de Wolski
Sean de Wolski 2013-1-17
@Raymond, The for-loops will smoke ind2sub() any day of the week for large arrays. ind2sub() is convenient not fast.
Matt J
Matt J 2013-1-17
Don't know what ind2sub has to do with anything, but the for-loop approach is definitely not faster:
A=[1 1 1 1; 1 1 2 3; 1 2 3 1; 1 1 1 2];
B=[1 2 3];
A(10000,1)=0;
tic;
[j,i]=ind2sub(fliplr(size(A)), strfind(reshape(A.',1,[]),B).' );
toc
%Elapsed time is 0.001019 seconds.
####################
tic
s = size(B) - 1;
n = size(A) - s;
out = [];
for ii = 1:n(1)
i1 = ii : ii + s(1);
for jj = 1:n(2)
if isequal(A(i1,jj : jj + s(2)),B)
out = [out;[ii,jj]];
end
end
end
toc;
%Elapsed time is 0.039563 seconds.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Mathematics 的更多信息

标签

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by