0

I have a sequence of integers, say arr = [1,5,2,2,5,1].

I need a structure, say Counter, that can tell me how many times the integer appears.

I have the following code but it won't work since isfield cannot be used in this way.

for i = 1 : length(arr)
  if ~isfield(Counter, i)
    Counter{i} = 0;
  end
  Counter{i} = Counter{i} + 1
end

So is there any elegant way that can accumulate the number of appearance of an integer sequence?

chappjc
  • 30,359
  • 6
  • 75
  • 132
SolessChong
  • 3,370
  • 8
  • 40
  • 67

2 Answers2

3
A = [1 2 1 2 3 3 1 4 5 5 6];
numbers = unique(A); % [1, 2, 3, 4, 5, 6] unique elements
count = histc(A, numbers); % [3, 2, 2, 1, 2, 1] occurrence of the element

The two core commands are unique and histc.

Ray
  • 2,472
  • 18
  • 22
2

Two other possibilities, in addition to histc:

  1. Use bsxfun to test for equality and then sum all coincidences for each number:

    A = [1 2 1 2 3 3 1 4 5 5 6];
    count = sum(bsxfun(@eq, A(:), min(A):max(A)));
    
  2. Use accumarray to sum 1 for each occurrence of each number:

    count = accumarray(A(:)-min(A)+1, 1, []).';
    

In both cases, count(1) is the number of ocurrences of min(A), count(2) is the number of ocurrences of min(A)+1, ..., count(end) is the number of occurrences of max(A) (some of which may be zero).

Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
  • 1
    My two favorite functions in one answer. However, if `min(A)>1`, then `count(1)` from `accumarray` will be zero instead of the count because it gets padded with zeros. I think you'd need to do `count = accumarray(A(:), 1).'; count(1:min(A)-1)=[]` or something similar. And if `A` can be negative, then it could get ugly, having to use `unique` first. – chappjc Dec 20 '13 at 18:25
  • @chappjc I knew you'd like this answer, having these two functions :-) (two of my favourite too). Thanks for your insightful comments. I have corrected by adding `-min(A)+1` to `A` – Luis Mendo Dec 20 '13 at 18:32