Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.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
C++ 如何解决可能的唯一组合问题_C++_Performance_Combinations - Fatal编程技术网

C++ 如何解决可能的唯一组合问题

C++ 如何解决可能的唯一组合问题,c++,performance,combinations,C++,Performance,Combinations,我需要一个大数的组合算法。我在StackOverflow上发现了一些东西,但实现并不完全正确。如果向量的大小大于22-24且k更大,则下面的代码将运行错误 #包括 使用名称空间std; 模板 无效打印(常量T&c、整数组合) { int n=c.size(); 对于(int i=0;i>i)&1) CUT< P>之所以失败,是因为你发布的原始算法是利用了一些比特计算,它实际上是把一个 int 类型的每个位看作不同的数字,并且根据编译器定义的 int ,你可以被限制为32或64的最大值 n>代码

我需要一个大数的组合算法。我在StackOverflow上发现了一些东西,但实现并不完全正确。如果向量的大小大于22-24且k更大,则下面的代码将运行错误

#包括
使用名称空间std;
模板
无效打印(常量T&c、整数组合)
{
int n=c.size();
对于(int i=0;i>i)&1)

CUT< P>之所以失败,是因为你发布的原始算法是利用了一些比特计算,它实际上是把一个<代码> int <代码>类型的每个位看作不同的数字,并且根据编译器定义的<代码> int <代码>,你可以被限制为32或64的最大值<代码> n>代码>。d还将所有
int
声明更改为
int64\t
,以强制将它们定义为64位

但是,这样做仍然会将最大
n
限制为64。(事实上,它被限制为
位大小-2
62
30
,因此不能完全确定为什么会被限制在23左右)真正的解决方案是将所有
int
更改为
std::bitset
,这样它就可以存储
SIZE\u MAX
的最大
n

  • 代码如下:
#包括
#包括
#包括
模板
void pretty_print(常量std::vector&c,std::位集组合)
{
int n=c.size();
对于(int i=0;i>i)&std::bitset(1))!=std::bitset(0))

什么是“大数组合算法”?例如有一个向量{30,30,30,30,30,30,30,60,60,60,60,60,60,90,90,90,90,90,90},当你试图用8来求这个向量的组合时,它做得不正确。我也认为位计算可能是错误的,但我不擅长按位运算。我不太理解while循环。你能准确地描述“大数组合算法”是什么吗?这对我来说意味着什么“用8求这个向量的组合“?据我所知,您希望获得
n
-元素集的所有不同
k
-元素子集。一种方法是使用int之类的基元类型并使用位移位。另一种方法是使用位集。但两种方法都必须避免重复。另一种方法是将元素重新构造为无序映射
{30:8,60:8,90:8}
并存储向量中的元素数:
{0,0,8}
。使用这些元素创建所有置换。然后将向量增加到
{0,1,7}
并创建所有排列。最后你将得到所有可能的组合。没有重复。@ThomasSablik-hmm你说的最后一种方法可能很好。我认为它可以用来编码。首先谢谢,我还在为项目的UI使用QT,也许在QT中可以有一些数据类型。但是,该程序在最后将是32位的部署。顺便说一下,我不知道是谁投的票。因为我是新来的,所以我不能vote@BilalCan我已经更新了我的代码,但是它们的运行速度并没有那么快,因为我不擅长实现逐位计算。另外,如果只处理nCk,链接中的其他方法也不会那么慢≈ 5000,除非你想找到n的解决方案≈ 5000您的代码产生重复:OP要求唯一的组合。@ThomasSablik您是对的,但我试图解决主要问题,他发现如果
n
大于某个值,代码将无法运行amount@Ranoiaetep您的代码有一个问题。位集需要编译时常量表达式,但我的ve的大小ctor实际上在运行时发生了变化。因此编译器给出了错误。根据输入,我应该编写const int n=degree_list_loop.size(),在您的算法中,我不能这样做,因为它是运行时表达式。
#include <iostream>
#include <vector>
#include <bitset>

template<size_t bitSize>
void pretty_print(const std::vector<std::bitset<bitSize>>& c, std::bitset<bitSize> combo)
{
    int n = c.size();
    for (int i = 0; i < n; ++i) {
        if (((combo >> i) & std::bitset < bitSize>(1)) != std::bitset <bitSize>(0))
            std::cout << c[i].to_ullong() << ' ';
    }
    std::cout << std::endl;
}


template<size_t bitSize>
bool smallerThan(std::bitset<bitSize> bits1, std::bitset<bitSize> bits2)
{
    for (size_t i = bitSize - 1; i > 0; i--)
    {
        if (bits1[i] < bits2[i])
        {
            return true;
        }
    }
    return false;
}


template<size_t bitSize>
std::bitset<bitSize> bitAddition(std::bitset<bitSize> bits1, std::bitset<bitSize> bits2)
{
    std::bitset<bitSize> carry;
    while (bits2 != std::bitset<bitSize>(0))
    {
        carry = bits1 & bits2;
        bits1 = bits1 ^ bits2;
        bits2 = carry << 1;
    }
    return bits1;
}


template<size_t bitSize>
std::bitset<bitSize> bitSubtraction(std::bitset<bitSize> bits1, std::bitset<bitSize> bits2)
{
    while (bits2 != std::bitset<bitSize>(0))
    {
        std::bitset<bitSize> borrow = (~bits1) & bits2;
        bits1 = bits1 ^ bits2;
        bits2 = borrow << 1;
    }
    return bits1;
}



template<size_t bitSize>
std::bitset<bitSize> bitSubtractionStopAt0(std::bitset<bitSize> bits1, std::bitset<bitSize> bits2)
{
    while (bits2 != std::bitset<bitSize>(0))
    {
        std::bitset<bitSize> borrow = (~bits1) & bits2;
        bits1 = bits1 ^ bits2;
        bits2 = borrow << 1;
        if (bits1 == std::bitset<bitSize>(0)) return bits1;
    }
    return bits1;
}


template<size_t bitSize>
std::bitset<bitSize> bitDivision(std::bitset<bitSize> dividend, std::bitset<bitSize> divisor)
{
    std::bitset<bitSize> quotient(0);
    while (smallerThan(std::bitset<bitSize>(0), dividend))
    {
        dividend = bitSubtractionStopAt0(dividend, divisor);
        quotient = bitAddition(quotient, std::bitset<bitSize>(1));
    }
    return quotient;
}




template<size_t bitSize>
void combo(const std::vector<std::bitset<bitSize>>& c, int k)
{
    auto n = c.size();
    std::bitset<bitSize> one(1);
    std::bitset<bitSize> combo(bitSubtraction((one << k), std::bitset<bitSize>(1)));


    while (smallerThan(combo, (one << n)))
    {
        pretty_print(c, combo);
        auto negCombo = combo;
        negCombo.flip();
        for (size_t i = 0; i < bitSize; i++)
        {
            negCombo.flip(i);
            if (negCombo[i])
            {
                break;
            }
        }
        std::bitset<bitSize> x = combo & negCombo;
        std::bitset<bitSize> y;
        bool tempBit = 0;
        for (size_t i = 0; i < bitSize; i++)
        {
            y[i] = combo[i] ^ x[i];
            if (tempBit)
            {
                if (!y[i])
                {
                    tempBit = 0;
                }
                y[i] = y[i] ^ 1;
            }
            if (combo[i] & x[i])
            {
                tempBit = 1;
            }
        }
        std::bitset<bitSize> z = (combo & ~y);
        combo = bitDivision(z, x);
        combo >>= 1;
        combo |= y;
    }
}

int main()
{
    const int n = 500;
    int k = 2;
    std::bitset<(n + 2)> n_bits(n);
    std::vector<std::bitset<n + 2>> people;
    for (unsigned long i = 1; i < n_bits.to_ullong() + 1; ++i) { people.push_back(i); }

    combo(people, k);

    return 0;
}