Подход 1
Это занимает много памяти, так как создает промежуточную n
× n
логическую матрицу, где n
- размер x
:
result = sum(triu(bsxfun(@eq, x, x.')))==1;
Начиная с R2016b, это можно выразить более кратко как
result = sum(triu(x==x.'))==1;
Как это работает
bsxfun(@eq, x, x.')
(или x==x.'
) создает квадратную матрицу сравнений на равенство.
triu
сохраняет только верхнюю треугольную часть, так что каждый элемент сравнивается только с предыдущими или с самим собой.
sum
дает сумму каждого столбца.Если сумма равна 1
, это означает, что элемент не равен ни одному из предыдущих элементов, а только самому себе.
Подход 2
Это немного более эффективно для памяти.Создается промежуточная логическая матрица m
× n
, где m
- количество уникальных элементов, а n
- общее количество элементов:
xu = unique(x);
result = any(diff([false(numel(xu),1) bsxfun(@eq, x, xu.')],[],2)==1);
Начиная с R2016b, вторая строкаможно заменить на
result = any(diff([false(numel(xu),1) x==xu.'],[],2)==1);
Как это работает
Это создает матрицу, скажем A
, сравнений каждого уникального элемента x
(индекс строки A
)с каждым элементом x
(индекс столбца A
).Пусть B
обозначает результат добавления столбца от false
к A
.
Элемент, который появляется в x
впервые, соответствует подпоследовательности [0 1]
в соответствующей строкеB
.Чтобы обнаружить это, diff
применяется вдоль каждой строки, и результат сравнивается с 1
(который является шагом между элементами в [0 1]
).