在PHP(或任何语言)中,可以合并2个位掩码,同时保持;“身份”;原始比特数?
这可能是一个非常愚蠢的问题,但它只是在我脑海中闪过,我想肯定知道它会很有趣 下面是一个场景: 用户一周中的每一天都有3个选项:上午、下午和下班。这些都是相互排斥的选择,因此没有选择在同一天的上午和下午同时工作 因此,如果我想将其AM移位和PM移位存储为单独的位掩码,并且User1选择以下选项:在PHP(或任何语言)中,可以合并2个位掩码,同时保持;“身份”;原始比特数?,php,bit-manipulation,Php,Bit Manipulation,这可能是一个非常愚蠢的问题,但它只是在我脑海中闪过,我想肯定知道它会很有趣 下面是一个场景: 用户一周中的每一天都有3个选项:上午、下午和下班。这些都是相互排斥的选择,因此没有选择在同一天的上午和下午同时工作 因此,如果我想将其AM移位和PM移位存储为单独的位掩码,并且User1选择以下选项: S M T W Th F Sa A P X A X P A $shifts['User1']['AM'] = 73; // 1001001
S M T W Th F Sa
A P X A X P A
$shifts['User1']['AM'] = 73; // 1001001
$shifts['User1']['PM'] = 34; // 0100010
我希望:
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;
有没有一种常见的方法可以做到这一点,或者我认为这是完全错误的?您有两种选择
前者更容易检查/比较,但后者在速度方面更有效。这里有两个选项
前者更容易检查/比较,但后者在速度方面更有效。要以二进制形式写入文字值,请使用:
0b1001001
,或十六进制:0x49
,而不是十进制:73
位图只会给出true或false,因此无法通过将两个位图压缩为一个来表示三个值(AM、PM、X)
我认为你的想法是错误的(其他人可能有一个我想不出来的更聪明的解决方案)。一个字符数组A、P、X可能同样适用于此。您可以合并数组(因此它与字符串不同)。要以二进制形式写入文字值,请使用:
0b1001001
,或十六进制:0x49
,而不是十进制:73
位图只会给出true或false,因此无法通过将两个位图压缩为一个来表示三个值(AM、PM、X)
我认为你的想法是错误的(其他人可能有一个我想不出来的更聪明的解决方案)。一个字符数组A、P、X可能同样适用于此。您可以合并数组(因此它与字符串不同)。是的,这是可能的。请参见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'
它回答了你的问题吗
另外,我使用Python,因为您明确指出它可以是任何编程语言。我重载了|
运算符。操作的结果仍然是WorkShift
的实例,因此您可以使用它进行进一步处理。它还继承自str
,因此您也可以将其用作字符串
编辑:
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');
是的,这是可能的。请参见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'
它回答了你的问题吗
另外,我使用Python,因为您明确指出它可以是任何编程语言。我重载了|
运算符。操作的结果仍然是WorkShift
的实例,因此您可以使用它进行进一步处理。它还继承自str
,因此您也可以将其用作字符串
编辑:
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');
要以二进制方式表示三种状态,需要2位。例如,你可以说:
PM=01
AM=10
关=00
现在你有了这个:
A00A00A
转换为10000010
0P000P0
转换为0001 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
。要以二进制方式表示三种状态,您需要2位。例如,你可以说:
PM=01
AM=10
关=00
现在你有了这个:
A00A00A
转换为10000010
0P000P0
转换为0001 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
您将获得所需的结果。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);
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);
我想到了两件事:三元的,普通的,不使用位掩码来完成这类任务。哦,在一天结束时,我肯定我会将它们分开,或者使用其他逻辑来推断,等等。但是As和Ps的图像突然出现在我的脑海中,我想可能是“不,傻瓜,这就是它现在的工作方式”或者“哼,换个基数就行了“,所以我不得不把它扔到那里去确定。我想到了两件事:三元的,普通的,不使用位掩码来完成这类任务。哦,在一天结束时,我确定我要么将它们分开,要么使用其他逻辑来推断,等等。但是As和Ps的图像突然出现在我的脑海中,我想可能是其中之一“不,傻瓜,这就是它现在的工作原理”或“嗯,只是改变基数”,所以我不得不把它扔出去,以确定它是可以做到的。+1表示它可以做到。现在我只需要拿出我的反向工程帽,看看它是否可以在PHP中复制。@Anthony:是的,它可以实现。请参见PHP<5.3的示例(对于PHP>=5.3,它会更好):让我把它复制到我的本地服务器上