Поменять группы символов двоичного кода местами побитовыми операциями со сдвигом (C#)

С помощью поразрядных логических операций выполнить над данными (не над строкой символов) следующее преобразование. Найти в двоичном коде максимальные по длине группы соседних одинаковых бит со значениями 0 и 1 и поменять эти группы местами со сдвигом при необходимости других бит между этими группами.

Пример: 0000000110010111 -> 1111100100000000


Ответы (1 шт):

Автор решения: VladD

Давайте я не буду писать код (всё же это явно учебное задание), а подскажу идеи.

Для начала, вам нужно выяснить, где же находятся ваши максимальные по длине группы. Для этого имеет смысл пройтись по вашему числу (например, от старшего бита к младшему), и при проходе держать такую информацию:

  • значение текущей группы (0 или 1 или неизвестно)
  • длина текущей группы
  • начало текущей группы
  • начало и длина самой длинной группы нулевых бит (для пройденной части числа)
  • начало и длина самой длинной группы единичных бит (для пройденной части числа)

После этого шага вы будете знать позиции групп, которые нужно обменять. Получится как-то так:

[начальные биты] [первая группа] [биты между группами] [вторая группа] [финальные биты]

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

В вашем итоговом числе должно быть так:

[начальные биты] [вторая группа] [биты между группами] [первая группа] [финальные биты]

Вам придётся перенести [начальные биты] как есть. Затем вам нужно будет подсчитать, на сколько бит нужно сдвинуть [вторую группу], чтобы она стала на своё место. Затем идут [биты между группами], их тоже придётся сдвинуть. Затем [первая группа] (с ней та же история), и без сдвига [финальные биты].

Какие элементарные операции вам понадобятся?

Выяснить, бит с данным индексом равен 0 или 1, можно, сравнив (1 << bitNumber) & n (где n — ваше число) с нулём.

Выделить группу можно при помощи аналогичной, более хитрой операции (((1 << length) - 1) << startNumber) & n (подумайте, почему). Для сдвига группы применяйте просто << или >>.

Ну и для объединения кусков нужно просто |.

Дерзайте!

→ Ссылка