给定1 * N矩阵或数组,如何找到具有相同值的前4个元素,然后存储这些元素的索引?
PS: 我只是好奇。如果我们想找到价值差异在一定范围内的前4个元素,比如低于2,该怎么办?例如,M = [10,15,14.5,9,15.1,8.5,15.5,9.5],我要找的元素是15,14.5,15.1,15.5,指数是2,3,5, 7。
答案 0 :(得分:7)
如果你想在Matlab的数组'tab'中出现第一个值4次,你可以使用
num_min = 4
val=NaN;
for i = tab
if sum(tab==i) >= num_min
val = i;
break
end
end
ind = find(tab==val, num_min);
以
为例tab = [2 4 4 5 4 6 4 5 5 4 6 9 5 5]
你得到了
val =
4
ind =
2 3 5 7
答案 1 :(得分:2)
这是我的MATLAB解决方案:
array = randi(5, [1 10]); %# random array of integers
n = unique(array)'; %'# unique elements
[r,~] = find(cumsum(bsxfun(@eq,array,n),2) == 4, 1, 'first');
if isempty(r)
val = []; ind = []; %# no answer
else
val = n(r); %# the value found
ind = find(array == val, 4); %# indices of elements corresponding to val
end
示例:
array =
1 5 3 3 1 5 4 2 3 3
val =
3
ind =
3 4 9 10
首先,我们提取唯一元素列表。在上面使用的示例中,我们有:
n =
1
2
3
4
5
然后使用BSXFUN函数,我们将每个唯一值与我们拥有的整个矢量数组进行比较。这相当于以下内容:
result = zeros(length(n),length(array));
for i=1:length(n)
result(i,:) = (array == n(i)); %# row-by-row
end
继续我们得到的相同例子:
result =
1 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 1 1 0 0 0 0 1 1
0 0 0 0 0 0 1 0 0 0
0 1 0 0 0 1 0 0 0 0
接下来,我们在result
矩阵上调用CUMSUM来计算沿行的累积和。每行将告诉我们到目前为止所讨论的元素出现了多少次:
>> cumsum(result,2)
ans =
1 1 1 1 2 2 2 2 2 2
0 0 0 0 0 0 0 1 1 1
0 0 1 2 2 2 2 2 3 4
0 0 0 0 0 0 1 1 1 1
0 1 1 1 1 2 2 2 2 2
然后我们将它与四个cumsum(result,2)==4
进行比较(因为我们想要第四次出现元素的位置):
>> cumsum(result,2)==4
ans =
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
最后,我们调用FIND根据列顺序查找第一个出现的1
:如果我们逐列遍历上一步的矩阵,那么第一个出现的行{{ 1}}表示我们要查找的元素的索引。在这种情况下,它是第三行(1
),因此唯一向量中的第三个元素是答案r=3
。请注意,如果我们在原始数组中重复了4次或更多次元素,那么第一次出现的元素将首先在上面的表达式中逐列显示为val = n(r)
。
查找相应答案值的索引是对FIND的简单调用......
答案 2 :(得分:0)
这是C ++代码
std::map<int,std::vector<int> > dict;
std::vector<int> ans(4);//here we will store indexes
bool noanswer=true;
//my_vector is a vector, which we must analize
for(int i=0;i<my_vector.size();++i)
{
std::vector<int> &temp = dict[my_vector[i]];
temp.push_back(i);
if(temp.size()==4)//we find ans
{
std::copy(temp.begin(),temp.end(),ans.begin() );
noanswer = false;
break;
}
}
if(noanswer)
std::cout<<"No Answer!"<<std::endl;
答案 3 :(得分:0)
忽略这一点并使用Amro的强大解决方案。 。 。
以下是我在Matlab中的表现。矩阵可以是任何大小并包含任何范围的值,这应该有效。此解决方案将自动找到一个值,然后找到前4个元素的指示,而不是先验地提供搜索值。
tab = [2 5 4 5 4 6 4 5 5 4 6 9 5 5]
%this is a loop to find the indicies of groups of 4 identical elements
tot = zeros(size(tab));
for nn = 1:numel(tab)
idxs=find(tab == tab(nn), 4, 'first');
if numel(idxs)<4
tot(nn) = Inf;
else
tot(nn) = sum(idxs);
end
end
%find the first 4 identical
bestTot = find(tot == min(tot), 1, 'first' );
%store the indicies you are interested in.
indiciesOfInterst = find(tab == tab(bestTot), 4, 'first')
答案 4 :(得分:0)
由于我无法轻易理解某些解决方案,因此我做了一个:
l = 10; m = 5; array = randi(m, [1 l])
A = zeros(l,m); % m is the maximum value (may) in array
A(sub2ind([l,m],1:l,array)) = 1;
s = sum(A,1);
b = find(s(array) == 4,1);
% now in b is the index of the first element
if (~isempty(b))
find(array == array(b))
else
disp('nothing found');
end
我发现这更容易想象。它填补了&#39; 1&#39;在方阵的所有位置,其中数组中的值存在 - 根据它们的位置(行)和值(列)。这可以很容易地总结并映射到原始数组。缺点:如果数组包含非常大的值,A也可能相对较大。
答案 5 :(得分:0)
你的PS问题更复杂。我没有时间检查每个案例,但这个想法就在这里:
M=[10,15,14.5,9,15.1,8.5,15.5,9.5]
val = NaN;
num_min = 4;
delta = 2;
[Ms, iMs] = sort(M);
dMs = diff(Ms);
ind_min=Inf;
n = 0;
for i = 1:length(dMs)
if dMs(i) <= delta
n=n+1;
else
n=0;
end
if n == (num_min-1)
if (iMs(i) < ind_min)
ind_min = iMs(i);
end
end
end
ind = sort(iMs(ind_min + (0:num_min-1)))
val = M(ind)