C++ 非递归二进制字符串置换生成器

C++ 非递归二进制字符串置换生成器,c++,C++,所以我正在研究一个问题,我需要生成二进制字符串的排列,这些字符串不仅有特定的长度,而且包含特定数量的1和0。我有一个算法可以做到这一点,但它是一个递归算法,我处理的是64位无符号整数,因此它们可能太大,函数无法处理。我希望有人能帮我,或者提出另一种算法,让我看看。任何帮助都将不胜感激。如果递归操作正确,您可以处理长度为64或更多的二进制序列 在下面的算法中,递归的深度受序列长度的限制(在您的例子中是64),在每个递归级别中,我们只在堆栈上放置几个字节。我们不存储所有结果,而是在序列准备就绪时输出

所以我正在研究一个问题,我需要生成二进制字符串的排列,这些字符串不仅有特定的长度,而且包含特定数量的1和0。我有一个算法可以做到这一点,但它是一个递归算法,我处理的是64位无符号整数,因此它们可能太大,函数无法处理。我希望有人能帮我,或者提出另一种算法,让我看看。任何帮助都将不胜感激。

如果递归操作正确,您可以处理长度为64或更多的二进制序列

在下面的算法中,递归的深度受序列长度的限制(在您的例子中是64),在每个递归级别中,我们只在堆栈上放置几个字节。我们不存储所有结果,而是在序列准备就绪时输出序列,这样就不会在内存中积累大量序列。注意
s
变量是如何通过递归传递的

#include <functional>
#include <iostream>

void create_all_binary_subsequence(std::string& s, int offset, int num_of_ones, std::function<void(const std::string& s)> callback)
{
    if (num_of_ones == 0)
        callback(s);
    else {
        for (int i = offset; i <= (int)s.size() - num_of_ones; ++i) {
            s[i] = '1';
            create_all_binary_subsequence(s, i + 1, num_of_ones - 1, callback);
            s[i] = '0';
        }
    }
}

void create_all_binary_sequences(int num_of_ones, int length, std::function<void(const std::string& s)> callback) {
    std::string s(length, '0');
    create_all_binary_subsequence(s, 0, num_of_ones, callback);
}

int main(int argc, char *argv[])
{
    create_all_binary_sequences(3, 5, [](const std::string& s) {
        std::cout << s.c_str() << "\n";
    });
    return 0;
}

如果递归正确,可以处理长度为64或更多的二进制序列

在下面的算法中,递归的深度受序列长度的限制(在您的例子中是64),在每个递归级别中,我们只在堆栈上放置几个字节。我们不存储所有结果,而是在序列准备就绪时输出序列,这样就不会在内存中积累大量序列。注意
s
变量是如何通过递归传递的

#include <functional>
#include <iostream>

void create_all_binary_subsequence(std::string& s, int offset, int num_of_ones, std::function<void(const std::string& s)> callback)
{
    if (num_of_ones == 0)
        callback(s);
    else {
        for (int i = offset; i <= (int)s.size() - num_of_ones; ++i) {
            s[i] = '1';
            create_all_binary_subsequence(s, i + 1, num_of_ones - 1, callback);
            s[i] = '0';
        }
    }
}

void create_all_binary_sequences(int num_of_ones, int length, std::function<void(const std::string& s)> callback) {
    std::string s(length, '0');
    create_all_binary_subsequence(s, 0, num_of_ones, callback);
}

int main(int argc, char *argv[])
{
    create_all_binary_sequences(3, 5, [](const std::string& s) {
        std::cout << s.c_str() << "\n";
    });
    return 0;
}

我建议使用标准库来完成此任务。您可以使用
std::next_permutation
功能,该功能将为您提供所有可能的排列。请看一看这个例子:

#include <iostream>
#include <algorithm>
#include <array>

template <class T>
void print(const T& array)
{
    std::cout << "{ ";
    for(bool i : array) { std::cout << i << " "; }
    std::cout << "}" << std::endl;
}

int main()
{
    std::array<bool, 5> data = { false, false, true, true, true };

    print(data);

    while(std::next_permutation(std::begin(data), std::end(data)))
    {
            print(data);
    }
}
编辑:

如果您希望能够在运行时选择1和0的数量,并且需要以字符串的形式排列,您可以将第一个排列准备为
std::string
,并在其上使用
std::next_permutation
。例如:

#include <iostream>
#include <algorithm>
#include <string>

std::string constructFirstPermutation(size_t numberOfZeros, size_t numberOfOnes)
{
    std::string result;
    result.reserve(numberOfZeros + numberOfOnes);
    result.append(numberOfZeros, '0');
    result.append(numberOfOnes, '1');

    return result;
}

int main()
{
    std::string data = constructFirstPermutation(5,10);

    std::cout << data << std::endl;

    while(std::next_permutation(std::begin(data), std::end(data)))
    {
        std::cout << data << std::endl;
    }
}
#包括
#包括
#包括
std::string constructionfirstpermutation(size\t numberofzero,size\t numberofone)
{
std::字符串结果;
结果.保留(numberOfZeros+numberofone);
result.append(numberOfZeros,'0');
结果。追加(numberOfOnes,'1');
返回结果;
}
int main()
{
std::string data=constructFirstPermutation(5,10);

std::cout我建议使用标准库完成此任务。您可以使用
std::next_permutation
函数,该函数将为您提供所有可能的排列。请查看此示例:

#include <iostream>
#include <algorithm>
#include <array>

template <class T>
void print(const T& array)
{
    std::cout << "{ ";
    for(bool i : array) { std::cout << i << " "; }
    std::cout << "}" << std::endl;
}

int main()
{
    std::array<bool, 5> data = { false, false, true, true, true };

    print(data);

    while(std::next_permutation(std::begin(data), std::end(data)))
    {
            print(data);
    }
}
编辑:

如果您希望能够在运行时选择1和0的数量,并且需要字符串形式的排列,您可以将第一个排列准备为
std::string
,并在其上使用
std::next_permutation
。示例:

#include <iostream>
#include <algorithm>
#include <string>

std::string constructFirstPermutation(size_t numberOfZeros, size_t numberOfOnes)
{
    std::string result;
    result.reserve(numberOfZeros + numberOfOnes);
    result.append(numberOfZeros, '0');
    result.append(numberOfOnes, '1');

    return result;
}

int main()
{
    std::string data = constructFirstPermutation(5,10);

    std::cout << data << std::endl;

    while(std::next_permutation(std::begin(data), std::end(data)))
    {
        std::cout << data << std::endl;
    }
}
#包括
#包括
#包括
std::string constructionfirstpermutation(size\t numberofzero,size\t numberofone)
{
std::字符串结果;
结果.保留(numberOfZeros+numberofone);
result.append(numberOfZeros,'0');
结果。追加(numberOfOnes,'1');
返回结果;
}
int main()
{
std::string data=constructFirstPermutation(5,10);


std::您是否考虑过使用std::next_排列?字符串的最大长度是多少?最大长度是64个字符您考虑过使用std::next_排列吗?字符串的最大长度是多少?最大长度是64个字符
向量
值得避免-遗憾的是,这不是您所期望的。
deque
>或者
vector
不太可能引起悲伤。@AlanStokes或者干脆
bool[n]
如果可能的话。@AlanStokes我对
vector
数组进行了更改
array
。我不知道
vector
有什么问题,谢谢有没有办法设置{false,false,true,true,true}部分动态?抱歉,但我对C++非常新。@ Pielb有很多方法,即你可以使用<代码> STD::String 做这个工作,我已经改变了我的答案,例如代码<矢量>代码>值得避免——很遗憾,不是你所期望的。<代码> DeQue>代码>或<代码>向量< /代码>不太可能引起悲伤。@ Alaltokes或Simpley
bool[n]
如果可能的话。@AlanStokes我把
vector
更改为
array
。我不知道
vector
有问题,谢谢有没有办法设置{false,false,true,true,true}部分动态?抱歉,但我对C++非常陌生。@ Pielyb有很多方法,即你可以使用<代码> STD::String 来做这项工作,我已经用示例来改变我的答案,谢谢帮助。但是我需要把生成的排列作为一个完整的字符串。我有没有办法用这个现有的代码来做?我试过玩了。和你在seq[i]上的演员们在一起,我还尝试将该字符数组设置为字符串,但两者都不起作用。好的。我修改了算法,使用std::string而不是字符数组。它现在更短更快了,谢谢你的帮助。但是我需要将生成的排列作为一个整串。我有没有办法使用现有代码来做到这一点?我尝试了d在seq[i]上玩你的cast,我也试着把char数组设置成字符串,但两个都不起作用。好的。我修改了算法,用std::string代替char数组。它现在更短更快了