Какова магия этого алгоритма?

Я немного смущен с кодом ответа SO.

Вопрос в вопросе просит решать функцию, которую читал бы array и возвращал 1 в случае, если он найдет 4 нуля в положениях последующих.

Здесь - код одного из ответов (который не очень хорошо, как интерпретировать):

function has0000(arr) {
    let c = 1;
    return +!arr.every( n => c = (c*2+!!n) & 0xF );
}

// Editado
// Equivalente
function has0000(arr) {
    let c = 1;
    return +!arr.every( n => {
      console.log('n', n, '; operación :', ((c*2+!!n) & 0xF).toString(2))
      c = (c*2+!!n) & 0xF;
      return c;
    } );
}


console.log('RESULTADO :', has0000([6, 7, 5, 0, 0, 0, 0, 3, 4, 0, 0, 1]));
console.log('-------------');
console.log('RESULTADO :', has0000([6, 7, 5, 0, 0, 0, 3, 4, 0, 0, 1]));

Какой тип "магии" прячется в этой операции?

c = (c*2+!!n) & 0xF;

Я верю в то, что понимаю, что в каждом повторении sobrescribe стоимость c из-за c*2 + - 1 (Завися, если число-> 0) и это сравнивает с "0xF", что представляет номер 15. Все же мне не удается понять, как он получает результат, который предлагается, как комментирует автор:

Только 4 самых недавних бита задержаны: Каждое повторение следующий бит прокручивается с правой стороны, в то время как тот, который занимает положение больше в левую сторону, уходит, всегда храня 4 бита. Если результат направляет 0 в любом моменте цикл для.

5
задан 23.05.2017, 15:39
1 ответ

Давайте замечать, что:

  • операция a & 0xF (bitwise AND) он равняется тому, чтобы оставлять себе 4 бита меньше значительные a. Следовательно, о коде мы можем думать в c как string 4 бит

  • !!n (двойное логическое отрицание) равняйся тому, чтобы конвертировать целое число n в booleano, со стоимостью true если n он отличный от 0. Когда целое число это складывает (+!!n) стоимость превратится в целое число (0 или 1). То есть a + !!n это то же самое что a + ( n != 0 ? 1 : 0).

  • c*2, для целого числа, равняйся тому, чтобы скроллировать биты (shift) место для левой стороны

  • c = (c*2+!!n) & 0xF равняйся тогда, чтобы "оставлять себе 3 бита меньше значительные c и прилагать (в правую сторону) новый бит 1 - кроме того, что n будьте нулем, в случае которого мы прилагаем один 0.

Инструкция c = (c*2+!!n) & 0xF он будет работать однажды для каждого элемента array; n это будет стоимость элемента, и c он будет считать начальной стоимостью стоимость предыдущего повторения. Единственный способ, которого c стойте 0 в каком-то моменте он, тогда, если у array есть четыре нуля последующих (что "опустошит" string c).

Метод arr.every возвратись true если инструкция возвращает true во всех повторениях - что произойдет в нашем случае если c он отличный от нуля во всех повторениях, а именно, если array нет у 4 нулей последующих.

Если (и только, если) у array есть 4 нуля последующих, c он будет стоить нуль в (по крайней мере) повторении, и every он возвратится false. Возвращенная стоимость отказывается сначала (для того, чтобы он возвратился true в этом случае), и он превращается в целое число с +!arr.every

9
ответ дан 24.11.2019, 13:33
  • 1
    Спасибо за explicaci и # 243; n!!:) – Jose Hermosilla Rodrigo 27.08.2016, 23:26

Теги

Похожие вопросы