2015-05-26 7 views
1

Учитывая значения в C, я хочу подсчитать, сколько раз я встречаю каждое из этих значений в векторе B. Например, если C = [1 2], я хотел бы подсчитать, сколько «1» находится в B и сколько «2» находятся в B, проверив элементы массива C.Считать элементы в одном массиве в другом массиве matlab

Однако код, который у меня есть, для подсчета до 5, но то, что должно быть истинным выходом, состоит в том, что число 1s равно 2, а число 2s равно 3.

Код, который я написал, показан ниже. Любая помощь будет, безусловно, оценена.

Мой код:

B = [ 1 2 1 4 5 2 2 ] 
C = [ 1 2 ] 

lb = length(B) 
lc = length(C) 

for i = 1:length(B) 
    for j = 1:length(C) 
     if B(1,i)==C(1,j) 
      c=c+1 
      A(i)=c 
     end 
    end 
end 

ответ

3

Santhan Salai дал скорректированный ответ если вы хотите придерживаться цикла s. Тем не менее, для повышения эффективности, можно добиться того, что вы хотите с bsxfun и sum, если вы не хотите, чтобы петля:

>> B = [ 1 2 1 4 5 2 2 ]; 
>> C = [ 1 2 ]; 
>> D = sum(bsxfun(@eq, B, C.'), 2) 

D = 

    2 
    3 

bsxfun хороший инструмент, который позволяет транслировать данные по одноэлементных размеров. В нашем случае я использовал функции equals, чтобы проверить равенство по элементам, и я транспонировал C так, чтобы он стал вектором столбца. Будет создано матрица, в которой у нас будет столько строк, сколько есть в C, и столько столбцов, сколько есть в B. Каждая строка этой выходной матрицы сообщает вам, какие элементы были равны каждому соответствующему элементу в C. C является транслировался таким образом, что мы получаем матрицу кучи [1;2] колонн делают пюре вместе стольких элементов, сколько в B и B транслируется таким образом, что мы получаем повторы B с таким количеством строк, что в C. Посредством элементарного равенства мы создадим логическую матрицу, в которой каждый элемент строки сообщает вам, какие элементы были равны соответствующему значению C. Все, что вам нужно сделать, это суммирование по столбцам, чтобы узнать, сколько элементов было равным каждому значению в C, поэтому вызов sum во втором измерении.


Если вы хотите излишеством, вы можете также использовать accumarray. Если предположить, что B и C состоять только из целых чисел, сделайте следующее:

>> B = [ 1 2 1 4 5 2 2 ]; 
>> C = [ 1 2 ]; 
>> D = accumarray(B.', 1);  

D = 

    2 
    3 
    0 
    1 
    1 

Это, однако, вычисляет частоту всех уникальных значений в B, и поэтому вы просто хотите первые две записи в D.


Еще одна альтернатива заключается в использовании histc:

>> B = [ 1 2 1 4 5 2 2 ]; 
>> C = [ 1 2 ]; 
>> D = histc(B, C) 

D = 

    2  3 

То, что вы в основном вычисления является гистограмма B в указанных бункеров, которые обозначаются на C.

+1

красиво сделано с 'bsxfun' –

+1

@SanthanSalai - Спасибо! Также хорошая работа, отлаживающая код цикла. Я собирался исправить это, но вы уже сделали это для меня LOL. – rayryeng

+0

Отличный ответ! Просто комментарий: 'accumarray' будет работать только для целочисленных значений (если вы не ставите перед ним« уникальный », третий вывод) –

1

Использование arrayfun может быть один альтернативный к вашей петле

out = arrayfun(@(x) sum(ismember(B,x)), C) 

Вот исправленный петля

count = zeros(1,numel(C)); 
for ii = 1:numel(C) 
    for jj = 1:numel(B) 
     if (C(ii) == B(jj)) 
      count(ii) = count(ii) + 1; 
     end 
    end 
end 
+0

Спасибо! Так чудесно ! – kgk