Matlab: как удалить элементы ячеек, у которых есть другие наборы как подмножества - PullRequest
1 голос
/ 06 мая 2020

У меня есть ячейка с массивами, перечисленными внутри:

C = {[1,2,3,4], [3,4], [2], [4,5,6], [4,5], [7]}

Я хочу вывести:

D = {[3,4], [2], [4,5], [7]}

Эти наборы в D - единственные наборы, которые содержат любые другие наборы в D сами по себе.

Пожалуйста, обратитесь к следующей ссылке для ответа на аналогичный вопрос. Несмотря на элегантность, я не смог (пока) изменить код, чтобы учесть мой конкретный вопрос.

Буду признателен за любую помощь с решением.

Спасибо!

Ответы [ 2 ]

3 голосов
/ 06 мая 2020

Для связанного сообщения вы можете сформировать матрицу s, которая представляет количество похожих элементов между всеми парами наборов. Результатом будет:

C = {[1,2,3,4], [3,4], [2], [4,5,6], [4,5], [7]};
n = cellfun(@numel,C);      % find length of each element.
v = repelem(1:numel(C),n);  % generate indices for rows of the binary matrix
[~,~,u] = unique([C{:}]);   % generate indices for rows of the binary matrix
b = accumarray([v(:),u(:)],ones(size(v)),[],@max,[],true); % generate the binary matrix
s = b * b.';                % multiply by its transpose
s(1:size(s,1)+1:end) = 0;   % set diagonal elements to 0(we do not need self similarity)
result=C(~any(n(:) == s)) ;

Но матрица может быть очень большой, поэтому лучше использовать al oop, чтобы избежать проблем с памятью:

idx=false(1,numel(C));
for k =1:numel(C)
    idx(k) = ~any(n == full(s(k, :))) ;
end
result=C(idx) ;

Или используйте векторизованный подход :

[r, c, v] = find(s) ;
idx = sub2ind(size(s), r, c) ;
s(idx) = v.' == n(r) ;
result = C(~any(s)) ;
1 голос
/ 06 мая 2020

Вы можете просто сделать это, сравнив каждый элемент со следующими его элементами и посмотреть, являются ли какие-либо из следующих элементов подмножеством текущего элемента, и если да, то удалите более крупный элемент. Вот простой код, который делает то, что вы ищете:

C = {[1,2,3,4], [3,4], [2], [4,5,6], [4,5], [7]};
% Initialize D with a copy of C
D = C; 

% Compare each element i with other elements j = i+1, i+2, ....
for i = 1:numel(C)-1
    for j = i+1:numel(C)
        % Check to see if C{j} exists in C{i}
        if contains(num2str(C{i}),num2str(C{j}))
            % Make unwanted elements empty
            D{i} = [];
        end
    end
end

% Remove empty elements
D(cellfun(@isempty,D)) = [];
...