В PHP (или любом другом языке), можно ли объединить 2 битовые маски при сохранении «идентичности» оригинальных битов? - PullRequest
2 голосов
/ 25 марта 2012

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

Итак, вот сценарий:

У пользователей есть 3 варианта для каждого дня недели: AM, PM и OFF. Это взаимоисключающие варианты, поэтому нет возможности работать и в AM, и в PM в один и тот же день.

Так что, если я хотел сохранить их AM-сдвиги и PM-сдвиги как отдельные битовые маски, а User1 выбирает следующее:

 S    M   T   W   Th   F   Sa
 A    P   X   A   X    P   A

У меня было бы следующее:

 $shifts['User1']['AM'] = 73;  //  1001001
 $shifts['User1']['PM'] = 34;  //  0100010

Теперь, если бы я просто хотел узнать, в какие дни работал User1, я бы, очевидно, мог просто сделать:

 $shifts['User1']['All'] = $shifts['User1']['AM'] | $shifts['User1']['PM'];

Или даже просто:

 $shifts['User1']['All'] = $shifts['User1']['AM'] + $shifts['User1']['PM'];

Но что, если бы я хотел, чтобы конечный результат отличал AM от PM, что-то вроде:

 $shifts['User1']['AM'] = A00A00A;
 $shifts['User1']['PM'] = 0P000P0;

Так что A и P оба считаются установленными, но это

 A00A00A | 0P000P0 = AP0A0PA;

Есть ли общий способ сделать это, или я думаю об этом совершенно неправильно?

Ответы [ 5 ]

1 голос
/ 25 марта 2012

Комментарий Minitech является правильным.Это троичная система счисления (потому что у вас есть 3 варианта для каждого значения).Чтобы вы могли сделать это:

$shifts['User1']['AM'] = '1001001';  //  A00A00A
$shifts['User1']['PM'] = '0200020';  //  0P000P0

$all = intval($shifts['User1']['AM'], 3) +
    intval($shifts['User1']['PM'], 3);

echo base_convert($all, 10, 3);
1 голос
/ 25 марта 2012

Чтобы представить три состояния в двоичном виде, вам нужно 2 бита.Например, вы можете сказать, что:

PM = 01

AM = 10

OFF = 00

Так что теперь выиметь это:

A00A00A переводится в 10 00 00 10 00 00 10

0P000P0 переводится в 00 01 00 00 00 01 00

Применение побитовой операции ИЛИ:

10 00 00 10 00 00 10
00 01 00 00 00 01 00
--------------------
10 01 00 10 00 01 10
A  P  0  A  0  P  A

Вы получите AP0A0PA, желаемый результат.

1 голос
/ 25 марта 2012

Чтобы записать литеральное значение в двоичном виде: 0b1001001 или в шестнадцатеричном виде: 0x49 вместо десятичного: 73.

Растровое изображение будет когда-либо давать только истину или ложь, поэтомуневозможно представить три значения (AM, PM, X), сжимая два растровых изображения в одно.

Я думаю, что вы думаете об этом неправильно (у других может быть более разумное решение, о котором я не могу думать, хотя).Массив символов A, P, X может быть так же хорош для этого.Вы можете объединять массивы (поэтому они не совпадают со строками).

1 голос
/ 25 марта 2012

Да, это возможно.Смотрите пример ниже в Python:

>>> class WorkShift(str):
    def __or__(self, val):
        def shift_calc(x, y):
            return x if x != '0' else y
        return WorkShift(''.join(map(shift_calc, self, val)))

>>> WorkShift('A00A00A') | WorkShift('0P000P0')
'AP0A0PA'

Отвечает ли он на ваш вопрос?

Ps.Я использовал Python, поскольку вы явно указали, что это может быть любой язык программирования.Я перегружен | оператором.Результат операции все еще является экземпляром WorkShift, поэтому вы можете использовать его для дальнейшей обработки.Он также наследуется от str, поэтому вы также можете использовать его как строку.

EDIT :

Аналогичное решение для PHP, но без перегрузки операторов, только на основепри обработке строк:

<?php

function shift_calc($x, $y) {
    return $x != '0' ? $x : $y;
};

function shift_sum($am, $pm) {
    return implode(array_map('shift_calc', str_split($am), str_split($pm)));
};

$result = shift_sum('A00A00A', '0P000P0');

, где $result - строка со следующим значением: "AP0A0PA" (см. подтверждение здесь: http://ideone.com/NbTEJ).

0 голосов
/ 25 марта 2012

У вас есть два варианта здесь.

  1. Чередование

    Исходная битовая маска разложена, а новая битовая маска вставлена ​​в новые «дыры».

    APAPAPAPAPAPAP
    
  2. Добавить

    Новая битовая маска добавляется к старой битовой маске.

    AAAAAAAPPPPPPP
    

Первый легче проверять / сравнивать, но последний более эффективен в отношении скорости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...