Algorithm 具有给定OR值的对数

Algorithm 具有给定OR值的对数,algorithm,bit-manipulation,Algorithm,Bit Manipulation,是否可以编写一个函数,该函数接受一个由n个整数和一个整数k组成的数组,并在优于O(n2)的时间内返回按位OR值等于k的数组元素对数 示例:如果我们有一个数组=[21,10,29,8]和k=31,那么函数应该返回2,因为有效对是(21,10)和(10,29) *为清晰起见* 21或10=31,21或29=29,21或8=29,10或29=31,10或8=10,29或8=29,所以答案是2 ****k是一个始终为31的常数。****假设时间单位是跨越k的字长上的基本运算,那么O(n+k2)是可能的:

是否可以编写一个函数,该函数接受一个由n个整数和一个整数k组成的数组,并在优于O(n2)的时间内返回按位OR值等于k的数组元素对数

示例:如果我们有一个数组=[21,10,29,8]和k=31,那么函数应该返回2,因为有效对是(21,10)和(10,29)

*为清晰起见* 21或10=31,21或29=29,21或8=29,10或29=31,10或8=10,29或8=29,所以答案是2


****k是一个始终为31的常数。****

假设时间单位是跨越k的字长上的基本运算,那么O(n+k2)是可能的:

#include <stdio.h>
#include <stdlib.h>

#define NumberOf(a) (sizeof (a) / sizeof *(a))


static unsigned Count(size_t N, unsigned *A, unsigned k)
{
    //  Count number of elements with each pattern of bits in k.
    unsigned *C = calloc(k + 1, sizeof *C);
    if (!C) exit(EXIT_FAILURE);
    for (size_t n = 0; n < N; ++n)
        if ((A[n] & ~k) == 0) ++C[A[n]];

    //  Count number of solutions formed with different values.
    unsigned T = 0;
    for (size_t i = 0; i < k; ++i)
    for (size_t j = i+1; j <= k; ++j)
        if ((i | j) == k)
            T += C[i] * C[j];

    //  Add solutions formed by same value (only possible when both are k).
    T += C[k] * (C[k]-1) / 2;

    free(C);

    return T;
}


int main(void)
{
    unsigned A[] = { 21, 10, 29, 8 };
    printf("%u\n", Count(NumberOf(A), A, 31));
}
#包括
#包括
#定义编号(a)(尺寸(a)/尺寸*(a))
静态无符号计数(大小N,无符号*A,无符号k)
{
//以k为单位计算每个位模式的元素数。
无符号*C=calloc(k+1,sizeof*C);
如果(!C)退出(退出失败);
对于(大小n=0;n对于(size_t j=i+1;j人们相信答案是“不”

假设您的
k
2^s-1
(因此它是
111…111
,二进制),并且所有数字最多为
k

a or b = k <=> (~a) and (~b) = 0.
这是一个一般的正交向量问题(OVP),流行的猜测认为它的求解速度不快于
O(n^2)
(我省略了一些细节)


请看这里的猜想1:。

你能提供一个示例数组=[21,10,29,8]和k=31,那么答案将是2,有效对是(21,10)和(10,29)。使用XOR?21=10101和10是01010,这样做(21-XOR 10)==31应该可以。我不确定你要用什么语言写这篇文章,但它只会检查每个空格中的一位。@geetransition:问题是“按位或”.哦,这是我对他们想要如何获得元素的猜测。仍然不确定它是如何获得成对的。编辑:Nvm,我已经重新阅读了这个问题…没有兄弟,Eric Postpuschil解决方案很棒,而且比0(n^2)快得惊人。你是如何测试它的?对于
k=(1@AdityaRoshan:这个答案和我的答案不同,因为他们回答不同的问题,取决于k是否被视为常数。@AdityaRoshan,将来,你应该在问题中声明你只对
k=31
@ReputationFarmer会做的,先生,谢谢你抽出时间,先生,对不起,我是新来的。很好的解决方案n先生,大粉丝:)可能值得在
for
j
循环之前添加一个检查
C[i]==0
110 or 101 = 111 <=> 001 and 010 = 0