对元组/列表中的所有整数进行按位与

发布于 2025-01-16 02:16:23 字数 932 浏览 0 评论 0原文

我有以下函数,其中 v 是整数元组,hits 是整数。该函数使用位掩码首先检查元组中的任何两个整数是否共享任何设置位,然后检查命中中的所有设置位是否也在元组中的整数之间设置

def noCollisionsBin(v, hits): 
    for x, y in itertools.combinations(v,2):    
        if (x & y): #if any 2 integers share set bits, they are overlapping
            return False
    tot = 0
    for i in v:
        tot |= i

    return (tot & hits) == hits #if all set bits of "hits" are set in the integers combined, the configuration is valid.

它可以工作,但我觉得应该有更多比使用 itertools.combinations() 更有效地检查第一个条件。我不想循环数组两次,而是只想执行一次,以类似于我使用 |= 组合 v 中整数的设置位的方式使用按位 AND 累积方式。我尝试了以下解决方案,但它产生了太多有效组合,表明第一个条件没有正确检查。

def noCollisionsBin(v, hits):
    tot_and = v[0]
    tot = v[0]
    for i in range(1,len(v)):
        tot |= v[i]
        tot_and &= v[i]
        if tot_and:
            return False
    
    return (tot & hits) == hits

我希望我所做的事情是有意义的。我对使用位运算符很陌生,任何帮助将不胜感激!

I have the following function, where v is a tuple of integers and hits is an integer. The function uses bitmasks to first check that no set bits are shared by any two integers in the tuple and then check that all set bits in hits are also set among the integers in the tuple

def noCollisionsBin(v, hits): 
    for x, y in itertools.combinations(v,2):    
        if (x & y): #if any 2 integers share set bits, they are overlapping
            return False
    tot = 0
    for i in v:
        tot |= i

    return (tot & hits) == hits #if all set bits of "hits" are set in the integers combined, the configuration is valid.

It works, but I feel like there should be a more efficient way to check the first condition than using itertools.combinations(). Instead of having to loop over the array twice, I would like to do it only once, using bitwise AND in a cumlative fashion similar to how I use |= to combine the set bits of the integers in v. I tried the following solution, but it yields too many valid combinations, indicating that the first condition isn't checked properly.

def noCollisionsBin(v, hits):
    tot_and = v[0]
    tot = v[0]
    for i in range(1,len(v)):
        tot |= v[i]
        tot_and &= v[i]
        if tot_and:
            return False
    
    return (tot & hits) == hits

I hope it makes sense what I am trying to do. I am quite new to using bit operators and any help would be much appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

↙厌世 2025-01-23 02:16:23

您没有提供任何代码来检查输出是否正确,但我相信以下内容会起作用。
关键思想是 tot 存储先前数字中设置的所有位。
如果发生任何碰撞,则 tot & v[i] 将设置重复位,因此将大于 0。

def noCollisionsBin(v, hits):
    tot = 0
    for i in range(len(v)):
        if tot & v[i] > 0:
            return False
        tot |= v[i]
    return (tot & hits) == hits

关于为什么第二个代码示例不能按预期工作的说明:
它仅检查 v 的前两个元素中的冲突。
如果它们确实发生碰撞,则循环将在第一次迭代中正确返回 False。
但是,如果不这样做,则 tot_and 将等于 0,并且在循环的剩余部分中将为 0,如 0 &对于任何x,x = 0

You didn't supply any code to check if the output is correct, but I believe the following will work.
The key idea is that tot stores all of the bits that were are set in previous numbers.
If there is any collision, then tot & v[i] will have the repeating bit set and hence will be greater than 0.

def noCollisionsBin(v, hits):
    tot = 0
    for i in range(len(v)):
        if tot & v[i] > 0:
            return False
        tot |= v[i]
    return (tot & hits) == hits

A note on why your second code sample doesn't work as expected:
it only checks for collision in the first two elements of v.
If they do collide, then the loop will correctly return False in the first iteration.
However, if they don't then tot_and will be equal to 0 and will be 0 for the remainder of the loop as 0 & x = 0 for any x.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文