Подсчитайте количество чередований в последовательности броска монеты - PullRequest
4 голосов
/ 08 сентября 2010

У меня есть последовательность единиц и нулей, и я хотел бы посчитать количество чередований. например,

x <- rbinom(10, 1, 1/2)
> x
 [1] 0 0 1 1 1 1 1 0 1 0

Таким образом, я хотел бы посчитать (в R), сколько раз последовательность чередуется (или переворачивается) от одного до нуля. В приведенной выше последовательности количество чередований (подсчитанное вручную) равно 4.

Ответы [ 4 ]

12 голосов
/ 08 сентября 2010

Вы можете использовать diff ():

> x <- rbinom(10,1,1/2)

> x
 [1] 0 0 0 1 1 1 1 0 1 0

> sum(diff(x)!=0)
[1] 4
6 голосов
/ 08 сентября 2010

Функция rle будет подсчитывать количество «прогонов» одного и того же значения в векторе. Следовательно, длина этого вектора (минус 1) дает вам количество изменений:

> x
 [1] 0 0 0 1 1 1 1 0 1 0
> rle(x)
Run Length Encoding
  lengths: int [1:5] 3 4 1 1 1
  values : num [1:5] 0 1 0 1 0
> length(rle(x)$lengths)-1
[1] 4

Может быть быстрее или медленнее, чем метод diff (), но он также дает вам длины пробега, если они вам нужны ...

3 голосов
/ 09 сентября 2010

Это определенно не превосходит разницу с точки зрения элегантности, но по-другому:

sum(x[-1] != head(x, n=-1))

В моей системе это кажется немного быстрее:

> x <- rbinom(1e6, 1, 0.5)
> system.time(replicate(100, sum(x[-1] != head(x, n=-1))))
   user  system elapsed 
  8.421   3.688  12.150 
> system.time(replicate(100, sum(diff(x) != 0)))
   user  system elapsed 
  9.431   4.525  14.248

Похоже, должно быть хорошее аналитическое решение для распределения числа неравных соседних элементов в последовательности.

0 голосов
/ 08 сентября 2010

Псевдокод (последовательность представляет собой массив с монетами):

variable count = 0
variable state = sequence[0]
iterate i from sequence[1] to sequence[n]
    if (state not equal sequence[i])
        state = 1 - state
        count++

счет должен быть вашим результатом

...