我不太确定如何说出这个问题。假设我有以下矩阵:
A=[1 0 0;
0 0 1;
0 1 0;
0 1 1;
0 1 2;
3 4 4]
鉴于第1行,我想找到所有行:
例如,在矩阵A中,如果给出第1行,我想找到第4行和第6行。
答案 0 :(得分:1)
现在无法测试,但我认为以下内容可行:
A=[1 0 0;
0 0 1;
0 1 0;
0 1 1;
0 1 2;
3 4 4];
B = zeros(size(A));
for ii = 1:size(A,1)
r = A(ii,:);
B(ii,1) = 1;
for jj = 2:size(A,2)
c = find(r(1:jj-1)==r(jj));
if numel(c) > 0
B(ii,jj) = B(ii,c);
else
B(ii,jj) = B(ii,jj-1)+1;
end
end
end
在最后,我们有一个数组B,其中“类似索引具有相似的值”,而您正在寻找的行现在是相同的。
现在你可以做到
[C, ia, ic] = unique(B,'rows','stable');
disp('The answer you want is ');
disp(ia);
您想要的答案将在变量ia
中。见http://www.mathworks.com/help/matlab/ref/unique.html#btb0_8v。我并非100%确定您可以在同一个电话中使用rows
和stable
参数 - 但我认为您可以。
尝试并查看它是否有效 - 如果您需要更多信息,请提出问题。
答案 1 :(得分:0)
这是一个简单的方法
B = NaN(size(A)); %//Preallocation
for row = 1:size(A,1)
[~,~,B(row,:)] = unique(A(row,:), 'stable');
end
find(ismember(B(2:end,:), B(1,:), 'rows')) + 1
答案 2 :(得分:0)
没有循环的简单解决方案:
row = 1; %// row used as reference
equal = bsxfun(@eq, A, permute(A, [1 3 2]));
equal = reshape(equal,size(A,1),[]); %// linearized signature of each row
result = find(ismember(equal,equal(row,:),'rows')); %// find matching rows
result = setdiff(result,row); %// remove reference row, if needed
关键是计算每一行的“签名”,即其元素的所有组合之间的相等关系。这是通过bsxfun
完成的。然后,可以使用ismember
轻松找到具有相同签名的行。
答案 3 :(得分:0)
谢谢,Floris。唯一的调用无法正常工作,我认为你也打算在其中使用矩阵B.这是我设法做的,虽然它不是那么干净:
A=[1 0 0 1;
0 0 1 3;
0 1 0 1;
0 1 1 0;
0 1 2 2;
3 4 4 3;
5 9 9 4];
B = zeros(size(A));
for ii = 1:size(A,1)
r = A(ii,:);
B(ii,1) = 1;
for jj = 2:size(A,2)
c = find(r(1:jj-1)==r(jj));
if numel(c) > 0
B(ii,jj) = B(ii,c);
else
B(ii,jj) = max(B(ii,:))+1; % need max to generalize to more columns
end
end
end
match = zeros(size(A,1)-1,size(A,2));
for i=2:size(A,1)
for j=1:size(A,2)
if B(i,j) == B(1,j)
match(i-1,j)=1;
end
end
end
index=find(sum(match,2)==size(A,2));
在嵌套循环中,我检查它下面的行中的元素是否与正确的列匹配。如果存在完美匹配,则该行应与行维度相加。
当我针对具体问题推广这个时,我正在处理矩阵填充一组基本大小(A,2)的数字。因此对于base 4和更高版本,else语句中需要max语句以表示不匹配。否则,对于给定行中的某些数字组合,如果没有,则可能会出现元素的重复。
答案 4 :(得分:0)
概述是将每一行减少为“签名”计数元素重复,即你的第1行变为1,2,然后检查是否有相同的签名。