Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 满足方程的位变换算法_Algorithm_Bit Manipulation - Fatal编程技术网

Algorithm 满足方程的位变换算法

Algorithm 满足方程的位变换算法,algorithm,bit-manipulation,Algorithm,Bit Manipulation,我一直在想如何解决这个问题,有人能给我一个解决这个问题的算法或步骤吗?我真的被难住了。代码不是必需的。我计划解决Python3,C和Rust 考虑四个数字:a、b、c和k。您必须更改a和b中最多k位,以形成满足方程式a'| b'=c.的数字a'和b'表示按位或运算 如果不存在这样的值,则返回-1。如果有多个解决方案,则尽可能小的一个;如果仍然存在多个解决方案,请将b'尽可能小 如果a中更改的位数为k.a(类似于b的k.b),则k.a+k.b慢方式: 迭代所有位 如果在a或b中设置了位,但在c中

我一直在想如何解决这个问题,有人能给我一个解决这个问题的算法或步骤吗?我真的被难住了。代码不是必需的。我计划解决Python3,C和Rust

考虑四个数字:a、b、c和k。您必须更改a和b中最多k位,以形成满足方程式a'| b'=c.的数字a'和b'表示按位或运算

如果不存在这样的值,则返回-1。如果有多个解决方案,则尽可能小的一个;如果仍然存在多个解决方案,请将b'尽可能小

如果a中更改的位数为k.a(类似于b的k.b),则k.a+k.b慢方式:

  • 迭代所有位
  • 如果在a或b中设置了位,但在c中未设置,则在a'和b'中重置它(计数:1或2)
  • 如果在c中设置,但在a和b中都缺少,则在b中设置(计数:1)
使用以下信息加快速度:

  • 在a:a&~c中查找额外的位(在任何情况下都需要删除)

  • 在b:b&~c中查找额外的位(在任何情况下都需要删除)

  • 查找缺少的位:~(a | b)和c(需要在b'中设置以保持a'小)


如果相应的位计数之和为则可行,我假设所需的结果为异或掩码,即数字为1,其中位应更改,0应保持不变(因此
a异或amask=a'
b异或bmask=b'

为了完整起见,
a'| b'
的结果有1位,其中a'或b'或两者都有1位,否则为0位

a'|b'=c
的第一个绝对必要的条件是a'和b'都没有1位,而c有0位。换句话说,要获得第一个amask和bmask,可以取a和b,并将每个位设置为0,其中c有1。换言之,要获得第一个amask和bmask,可以取a和b并将每个位设置为0,其中c的二进制补码为0

amask = a & (~c)
bmask = b & (~c)  
现在计算在amask和bmask中有多少位是1(使用一个简单的循环,或者使用一个在线的popcount函数),然后从k中减去这个。如果k为负值,则没有解(返回-1)

第二部分要求找到a和b都为0但c为1的位。简而言之:
temp_mask=c&((异或amask)|(异或bmask))

temp_mask是需要在a或b中设置为1的位(哪一位取决于“最小”的要求。但首先,pop count temp_mask也是,如果结果大于剩余的k,则没有解决方案(返回-1)

下一步很简单:
amask=amask|temp_mask

以前的amask有1,其中c是0,现在这个语句将不会重叠任何内容

现在,对于
a'|b'=c
,您至少有一个解决方案,即
(a异或amask)|(b异或bmask)=c

但可能还有一个a更小的,对吧

这也不是很难:在
(异或amask)
中为1但在
(异或amask)
中为0的每一位都可以被“移动”,即在
(异或amask)
中为0,在
(异或amask)
中为1。结果c将是相同的,但
(异或amask)
的数值将更小(最坏的情况可能是保持不变)

要实现这一点,请注意
无符号
和整数大小

完整伪代码:

amask = a & (~c)
bmask = b & (~c) 
temp_mask = c & ((a XOR amask) | (b XOR bmask))
amask = amask | temp_mask
temp_mask = (a XOR amask) & (~(b XOR bmask))  
amask = amask XOR temp_mask
bmask = bmask XOR temp_mask
amask = a & (~c)
bmask = b & (~c) 
temp_mask = c & ((a XOR amask) | (b XOR bmask))
amask = amask | temp_mask
temp_mask = (a XOR amask) & (~(b XOR bmask))  
amask = amask XOR temp_mask
bmask = bmask XOR temp_mask