C++ 求字符串向量的r-组合

C++ 求字符串向量的r-组合,c++,algorithm,combinations,C++,Algorithm,Combinations,我试图生成给定字符串列表的所有可能的r-组合。例如: vector<string> original(n); original[0] = "Brown"; original[1] = "Yellow"; original[2] = "Blue"; 与我交谈过的每个人都说使用下一个排列路线,但这会让我重复(我寻找的是组合,而不是排列…..因此在上面的示例中,在集合之后(黄色,蓝色),(蓝色,黄色)不应包括在内) 尝试以下步骤: 1) 创建一个由3位组成的序列 2) 因为r是2,所以将

我试图生成给定字符串列表的所有可能的r-组合。例如:

vector<string> original(n);
original[0] = "Brown";
original[1] = "Yellow";
original[2] = "Blue";
与我交谈过的每个人都说使用下一个排列路线,但这会让我重复(我寻找的是组合,而不是排列…..因此在上面的示例中,在集合之后(黄色,蓝色),(蓝色,黄色)不应包括在内)

尝试以下步骤:

1) 创建一个由3位组成的序列

2) 因为
r
是2,所以将最右边的两个位初始化为1

3) 输出向量中与启用位对应的项,例如,如果
位数组[0]
为1,则输出
原始[0]
,如果
位数组[1]
为1,则输出
原始[1]
,等等

4) 对位调用
next\u permutation()
,以获得“next”位模式

重复步骤3和4,直到下一个排列()为
false

因此,基本上,您需要一个
n
项的位数组来开始,并将最右边的
r
位初始化为1。然后使用
next\u排列
更改位模式。我建议你先在纸上做这件事,看看它是如何运作的

下面是一个例子。这是硬编码的3个项目,所以采取它的价值

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

void OutputVector (const std::vector<std::string>& theVect, bool* bArray, int nItems)
{
    for (int i = 0; i < nItems; ++i)
       if (bArray[i] == true)
         std::cout << theVect[i] << " ";
    std::cout << "\n";
}

using namespace std;

int main()
{
    std::vector<std::string> original = { "Brown", "Yellow", "Blue" };
    bool myBits[3] = { false };  // everything is false now
    myBits[1] = myBits[2] = true;  // set rightmost bits to true
    do  // start combination generator
    {
       OutputVector(original, myBits, 3);
    } while (next_permutation(myBits, myBits + 3));  // change the bit pattern
}
#包括
#包括
#包括
#包括
void OutputVector(const std::vector&theVect,bool*bArray,int nItems)
{
对于(int i=0;istd::cout您可以使用以下类似的方法:

template <typename T>
void Combination(const std::vector<T>& v, std::size_t count)
{
    assert(count <= v.size());
    std::vector<bool> bitset(v.size() - count, 0);
    bitset.resize(v.size(), 1);

    do {
        for (std::size_t i = 0; i != v.size(); ++i) {
            if (bitset[i]) {
                std::cout << v[i] << " ";
            }
        }
        std::cout << std::endl;
    } while (std::next_permutation(bitset.begin(), bitset.end()));
}
模板
无效组合(常数std::向量&v,std::大小\u t计数)
{

assert(countMy solution,比使用
std::next\u排列更快

#include "../combinations/combinations"
#include <iostream>
#include <string>
#include <vector>

int
main()
{
    std::vector<std::string> original(6);
    original[0] = "Brown";
    original[1] = "Yellow";
    original[2] = "Blue";
    original[3] = "Red";
    original[4] = "Green";
    original[5] = "Purple";
    for_each_combination(original.begin(), original.begin()+3, original.end(),
                         [](auto begin, auto end)
                         {
                              std::cout << "{";
                              bool print_comma = false;
                              for (; begin != end; ++begin)
                              {
                                   if (print_comma)
                                       std::cout << ", ";
                                   print_comma = true;
                                   std::cout << *begin;
                              }
                              std::cout << "}\n";
                              return false;
                         });
}
如果受限于C++98,或者您只是喜欢命名函数,则可以执行以下操作:

#include "../combinations/combinations"
#include <iostream>
#include <string>
#include <vector>

bool
print(std::vector<std::string>::const_iterator begin,
      std::vector<std::string>::const_iterator end)
{
    std::cout << "{";
    bool print_comma = false;
    for (; begin != end; ++begin)
    {
        if (print_comma)
            std::cout << ", ";
        print_comma = true;
        std::cout << *begin;
    }
    std::cout << "}\n";
    return false;
}

int
main()
{
    std::vector<std::string> original(6);
    original[0] = "Brown";
    original[1] = "Yellow";
    original[2] = "Blue";
    original[3] = "Red";
    original[4] = "Green";
    original[5] = "Purple";
    for_each_combination(original.begin(), original.begin()+3, original.end(),
                         print);
}
#包括“./组合/组合”
#包括
#包括
#包括
布尔
打印(std::vector::const_迭代器开始,
std::vector::const_迭代器(结束)
{

std::输入是否可以包含重复?如果您知道基于一系列位输出组合的算法,您仍然可以在位模式上使用next_permutation()。每个“开”的位表示组合中的一项。输出不能包含重复。输入是否可以包含重复。是否`{“棕色”、“黄色”、“棕色”}是有效输入吗?是的,那将是有效输入。通过我上面描述的算法,首先用铅笔和纸理解它,然后用真实代码。为了简单起见,只需创建一个包含3项的布尔数组,并将所有项设置为false,除了最右边的2项,即项1和项2(将它们设置为true)基本上,你使用布尔数组作为输出原始数组值的指南。@ NothyNasyII-发誓-另一个答案显示了上面所解释的算法的一个生动例子。但是如果你不理解C++的这个方面,那现在就不重要了。更重要的是理解算法是如何工作的,这就是为什么Y。你应该用铅笔和纸来“手”来做这件事。一旦你掌握了发生的逻辑,那么就使用你所学过的任何C++(不必是<代码> BITSET ,如下面的例子)。模拟算法。@Not_NSA_我发誓您可以通过调用
std::sort
,对原始向量进行排序。完全按照我描述的方式。+1。
{Brown, Yellow, Blue}
{Brown, Yellow, Red}
{Brown, Yellow, Green}
{Brown, Yellow, Purple}
{Brown, Blue, Red}
{Brown, Blue, Green}
{Brown, Blue, Purple}
{Brown, Red, Green}
{Brown, Red, Purple}
{Brown, Green, Purple}
{Yellow, Blue, Red}
{Yellow, Blue, Green}
{Yellow, Blue, Purple}
{Yellow, Red, Green}
{Yellow, Red, Purple}
{Yellow, Green, Purple}
{Blue, Red, Green}
{Blue, Red, Purple}
{Blue, Green, Purple}
{Red, Green, Purple}
#include "../combinations/combinations"
#include <iostream>
#include <string>
#include <vector>

bool
print(std::vector<std::string>::const_iterator begin,
      std::vector<std::string>::const_iterator end)
{
    std::cout << "{";
    bool print_comma = false;
    for (; begin != end; ++begin)
    {
        if (print_comma)
            std::cout << ", ";
        print_comma = true;
        std::cout << *begin;
    }
    std::cout << "}\n";
    return false;
}

int
main()
{
    std::vector<std::string> original(6);
    original[0] = "Brown";
    original[1] = "Yellow";
    original[2] = "Blue";
    original[3] = "Red";
    original[4] = "Green";
    original[5] = "Purple";
    for_each_combination(original.begin(), original.begin()+3, original.end(),
                         print);
}
template <class BidirIter, class Function>
Function
for_each_permutation(BidirIter first,
                     BidirIter mid,
                     BidirIter last,
                     Function f);

template <class BidirIter, class Function>
Function
for_each_reversible_permutation(BidirIter first,
                                BidirIter mid,
                                BidirIter last,
                                Function f);

template <class BidirIter, class Function>
Function
for_each_circular_permutation(BidirIter first,
                              BidirIter mid,
                              BidirIter last,
                              Function f);

template <class BidirIter, class Function>
Function
for_each_reversible_circular_permutation(BidirIter first,
                                         BidirIter mid,
                                         BidirIter last,
                                         Function f);

template <class BidirIter, class Function>
Function
for_each_combination(BidirIter first,
                     BidirIter mid,
                     BidirIter last,
                     Function f);