Вот мое решение 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
Затем мы вызываем CUMSUM для матрицы result
, чтобы вычислить накопленную сумму по строкам. В каждой строке будет указано, сколько раз данный элемент появлялся до сих пор:
>> 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
указывает Индекс элемента, который мы ищем. В данном случае это была третья строка (r=3
), поэтому третьим элементом в уникальном векторе является ответ val = n(r)
. Обратите внимание, что если у нас было несколько элементов, повторенных 4 или более раз в исходном массиве, то первый, появившийся в четвертый раз, сначала будет отображаться как 1
столбец за столбцом в приведенном выше выражении.
Поиск индексов соответствующего значения ответа - это простой вызов FIND ...