На входе мне дают несколько uint32_t
числа, которые на самом деле являются двоичными строками длиной 32. Я хочу создать двоичную строку (a.k.a. другое uint32_t
число) где n-й бит установлен в 1
если n-й бит в каждой заданной строке из входных данных одинаков.
Вот простой пример с 4-битной строкой (просто более простой пример той же проблемы):
вход: 0011, 0101, 0110
выход: 1000
так как: первый бит одинаков в каждой строке на входе, поэтому первый бит на выходе будет установлен на 1
и 2-й, 3-й и 4-й будут установлены в 0
потому что они имеют разные значения.
Каков наилучший способ получения выходных данных от данного ввода? Я знаю, что мне нужно использовать побитовые операторы, но я не знаю, какой из них и в каком порядке.
uint32_t getResult( const vector< uint32_t > & data ){
//todo
}
Вы хотите биты, где все исходные биты равны 1, и биты, где все исходные биты равны 0. Просто И исходные значения и НЕ исходных значений, а затем ИЛИ результаты.
uint32_t getResult( const vector< uint32_t > & data ){
uint32_t bitsSet = ~0;
uint32_t bitsClear = ~0;
for (uint32_t d : data) {
bitsSet &= d;
bitsClear &= ~d;
}
return bitsSet | bitsClear
}
Прежде всего, конечно, вам нужно перебрать вектор.
Тогда мы можем использовать XOR текущего элемента и следующий элемент. Сохраните результат.
Для следующей итерации сделайте то же самое: XOR текущего элемента со следующим элементом. Но затем побитовое ИЛИ с сохраненным результатом предыдущей итерации. Сохраните этот результат. Затем продолжайте, пока не выполните итерацию по всем (минус один) элементам.
Сохраненный результат является дополнением к тому, что вы хотите.
Принимая ваши примеры чисел (0011
, 0101
а также 0110
) то первая итерация у нас 0011 ^ 0101
что приводит к 0110
, Следующая итерация у нас 0101 ^ 0110
что приводит к 0011
, Побитовое ИЛИ с предыдущим результатом (0110 | 0011
) дает 0111
, Конец цикла и побитовое дополнение дают результат 1000
,