РЕДАКТИРОВАТЬ: Обновлен для использования более эффективного алгоритма.
Если эффективность равносильна из-за большого количества наборов в I
, то ваш лучший вариант, вероятно, состоит в том, чтобы свернуть ваши собственные оптимизированные циклы. Эта проблема имеет некоторое сходство с предыдущим вопросом о , как эффективно удалять наборы, которые являются подмножествами или равны другим . Разница здесь в том, что вас не интересует удаление подмножеств , просто дубликатов , поэтому код в моем ответе на другой вопрос можно изменить для дальнейшего сокращения количество сравнений.
Во-первых, мы можем признать, что нет смысла сравнивать наборы с разным количеством элементов, поскольку в этом случае они не могут совпадать. Итак, первым шагом является подсчет количества строк в каждом наборе, а затем цикл по каждой группе наборов с одинаковым количеством строк.
Для каждой из этих групп у нас будет два вложенных цикла: внешний цикл над каждым набором, начинающийся в конце наборов, и внутренний цикл над каждым набором, предшествующим этому. Если / когда найдено первое совпадение, мы можем пометить этот набор как «не уникальный» и разорвать внутренний цикл, чтобы избежать дополнительных сравнений. Запуск внешнего цикла в конце наборов дает нам дополнительный бонус, который устанавливается в I_unique
и будет поддерживать исходный порядок появления в I
.
А вот и полученный код:
I = {{'a' 'b' 'c' 'd' 'e'} ... %# The sample cell array of cell arrays of
{'a' 'b' 'c'} ... %# strings from the question
{'d' 'e'} ...
{'a' 'b' 'c' 'd' 'e'} ...
{'a' 'b' 'c' 'd' 'e'} ...
{'a' 'c' 'e'}};
nSets = numel(I); %# The number of sets
nStrings = cellfun('prodofsize',I); %# The number of strings per set
uniqueIndex = true(1,nSets); %# A logical index of unique elements
for currentSize = unique(nStrings) %# Loop over each unique number of strings
subIndex = find(nStrings == currentSize); %# Get the subset of I with the
subSet = I(subIndex); %# given number of strings
for currentIndex = numel(subSet):-1:2 %# Outer loop
for compareIndex = 1:currentIndex-1 %# Inner loop
if isequal(subSet{currentIndex},subSet{compareIndex}) %# Check equality
uniqueIndex(subIndex(currentIndex)) = false; %# Mark as "not unique"
break %# Break the inner loop
end
end
end
end
I_unique = I(uniqueIndex); %# Get the unique values