Удаление элементов из массива

Проблема:

У меня есть два массива A и B:

A = [0, 1, 2, 3]; %A will always be from 0 to N where N in this case is 3.

B = [0, 1, 3,   1, 9, 4, 6,    2, 5, 9, 10, 11,   3, 8, 1, 5, 9, 10]; 

weights_B = [3, 4, 5, 6]; 

Я хочу сравнить первый элемент A с первыми 3 элементами B, а второй элемент A со следующими 4 элементами B. Если элементы A равны, я удаляю его из B. Итак, в примере:

 if (A(1) == B(1:3))
 remove A(1) from B 

Сходным образом,

Я хочу сравнить A(2) со следующими 4 элементами B, то есть с B(4:7):

if (A(2) == B(4:7))
remove A(2) from B 

Я хочу сравнить A(3) со следующими 5 элементами B, то есть с B(8:12)

if (A(3) == B(8:12))
remove A(3) from B 

Я хочу сравнить A(4) со следующими 6 элементами B, то есть с B(13:18)

if (A(4) == B(13:18))
remove A(4) from B 

Примечание. Массив weights_B определяет количество элементов в B, которые должны соответственно сравниваться с A(1), A(2), .. , A(4).

Таким образом, в конце B должны быть следующие элементы:

  B = [1, 3, 9, 4, 6, 5, 9, 10, 11, 8, 1, 5, 9, 10]; 

Необходимое решение:

Есть ли способ сделать это без жесткого кодирования индексов?


person Anthony    schedule 22.06.2018    source источник
comment
Я только что прочитал ваш комментарий к ответу Шивы. Существует ли правило, какой элемент A следует сравнивать с каким диапазоном в B? Почему вы берете 3 элемента B по сравнению с A (1) и 4 элемента для A (2) и A (3) соответственно?   -  person Anton    schedule 22.06.2018
comment
@ Антон Я собираюсь перефразировать вопрос и сделать его более ясным.   -  person Anthony    schedule 22.06.2018
comment
подожди немного, у меня есть идея   -  person Anton    schedule 22.06.2018
comment
@Anton Я изменил описание с учетом необходимых правил. Надеюсь, это более понятно для вас. Большое спасибо!   -  person Anthony    schedule 22.06.2018
comment
Я выложил новую версию. попробуй пожалуйста   -  person Anton    schedule 22.06.2018


Ответы (5)


Вот способ без жесткого кодирования:

Bw = mat2cell(B, 1, weights_B); % split into chunks
result = cell(size(Bw)); % initiallize result
for k = 1: numel(A)
    result{k} = Bw{k}(Bw{k}~=A(k)); % fill each chunk of the result
end
result = [result{:}]; % concatenate into a row vector
person Luis Mendo    schedule 22.06.2018
comment
Спасибо за ваш ответ! Я выбираю ваш ответ, потому что это был самый быстрый способ вычислить мою проблему, когда я использую очень большие матрицы. - person Anthony; 22.06.2018

Для разнообразия вот способ сделать это с помощью splitapply. :

function out = q50982235
A = 0:3;
B = [0, 1, 3,   1, 9, 4, 6,    2, 5, 9, 10, 11,   3, 8, 1, 5, 9, 10]; 
weights_B = [3, 4, 5, 6];

a_ind = 0; % acts as a "global" variable for the inner function

G = repelem( 1:numel(weights_B), weights_B ); % this creates a vector of groups
out = cell2mat( splitapply(@movdif, B, G) );

function out = movdif(B)
  a_ind = a_ind + 1;
  out = {B(B ~= A(a_ind))};
end

end

Вышеприведенное работает, потому что порядок обрабатываемых групп предсказуем.

Это решение требует R2015b.

person Dev-iL    schedule 22.06.2018

Попробуй это

A = [0, 1, 2, 3]; 
B = [0, 1, 3,   1, 9, 4, 6,    2, 5, 9, 10, 11,   3, 8, 1, 5, 9, 10]; 

weights_B = A + A(end);

border_0 = zeros(size(A));
border_1 = zeros(size(A));

border_0(1) = 1;
border_1(end) = length(B);

for i= 2:length(A)
    border_0(i) = border_0(i-1) + weights_B(i-1);
    border_1(i-1) = border_0(i)-1;
end

C = [];
for i= 1:length(border_0)
    shift = 0;
    if (i > 1)
        shift = border_1(i-1);
    end

    C = [C  B(    find(B(border_0(i):border_1(i))~=A(i)) + shift     )]
end
person Anton    schedule 22.06.2018
comment
Что, если A = [0, 1, 2] и B = [0, 1, 3, 1, 4, 5, 6, 2, 3, 9, 11]; а теперь я также хочу сравнить 2 в A с 2, 3, 9, 11 в B. Ответ должен быть B = [1, 3, 4, 5, 6, 3, 9, 11]; Можно ли это сделать, не вводя индексы вручную? - person Anthony; 22.06.2018
comment
пожалуйста, прочитайте мой комментарий к вопросу. Нам нужно правило, описывающее сопоставление между элементами в A и диапазонами в B. - person Anton; 22.06.2018
comment
Это на самом деле не отвечает на вопрос. В вопросе конкретно говорится без жесткого кодирования индексов - person Luis Mendo; 22.06.2018

Поскольку вы хотите сравнить элементы A с первыми 3, а затем с 4 элементами B соответственно, вам нужно будет использовать индексы. Вы можете просто использовать цикл для этого.

for(int i=0;i<B.length;i++){
 if((A[0]==B[i])&&i<3){
 B[i]=B[i+1];
 }
 else if((A[0]==B[i])&&i>3){}
  B[i]=B[i+1];
 }

Затем отрегулируйте обновленный размер массива B.

person Ahmad Bin Shafaat    schedule 22.06.2018
comment
Изменить: в операторе else используйте A[1] - person Ahmad Bin Shafaat; 22.06.2018
comment
Это не код Matlab. Кроме того, в вопросе конкретно говорится без жесткого кодирования индексов - person Luis Mendo; 22.06.2018
comment
Пожалуйста, соблюдайте языковые теги, прикрепленные к вопросу. Вопрос помечен MATLAB. - person rayryeng; 22.06.2018

person    schedule
comment
Что, если A = [0, 1, 2] и B = [0, 1, 3, 1, 4, 5, 6, 2, 3, 9, 11]; а теперь я также хочу сравнить 2 в A с 2, 3, 9, 11 в B. Ответ должен быть B = [1, 3, 4, 5, 6, 3, 9, 11]; Можно ли это сделать, не вводя индексы вручную? - person Anthony; 22.06.2018
comment
Это на самом деле не отвечает на вопрос. В вопросе конкретно говорится без жесткого кодирования индексов - person Luis Mendo; 22.06.2018