我试图生成给定字符串列表的所有可能的r组合。例如:
vector<string> original(n);
original[0] = "Brown";
original[1] = "Yellow";
original[2] = "Blue";
在这种情况下,n = 3(3种颜色),例如,如果用户输入r = 2,则程序必须打印:
>Brown, Yellow
>Brown, Blue
>Yellow, Blue
我所谈过的每个人都说要使用next_permutation路线,但这会让我重复(我正在寻找组合,而不是排列.....所以在上面的例子中,在集合之后(黄色,蓝色),(蓝色) ,黄色)不应包括在内)。
答案 0 :(得分:2)
您可以使用以下内容:
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()));
}
答案 1 :(得分:0)
尝试以下步骤:
1)创建一系列3位。
2)由于r
为2,因此将最右边的两位初始化为1。
3)输出向量中与开启位相对应的项,例如,如果bitarray[0]
为1,则输出original[0]
,如果bitarray[1]
为1,则输出输出original[1]
等
4)对这些位调用next_permutation()
以获得“下一个”位模式。
重复步骤3和4,直到next_permutation()为false
。
所以基本上,你需要一些n
个项目来开始并将最右边的r
位初始化为1.然后你使用next_permutation
来改变位模式。我建议你先在纸上做这件事,看看它是如何运作的。
以下是一个例子。它有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
}
举个例子:
我们从这个位模式开始(调用位数组bitArray
):
011
这意味着我们输出original[1]
和original[2]
,因为bitArray[1]
和bitArray[2]
是“true”(设置为1)。
在这些位上调用next_permutation
时,位模式更改为:
101
我们输出original[0]
和original[2]
,因为bitArray[0]
和bitArray[2]
为“true”。
next_permutation
,更改位数组:
110
original[0]
和original[1]
。
next_permutation
将返回false,因为没有更多的排列。
完成。
答案 2 :(得分:0)
我的解决方案,比使用std::next_permutation
更快
#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;
});
}
输出:
{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}
如果受限于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);
}
源代码在boost软件许可下是开源的,但不是boost的一部分。随意使用。目的是该源代码可以免费使用,并鼓励免费使用。如果您的律师对此许可证不满意,请告诉我,我将尽力让他们感到高兴,免费。
相同的链接包括:
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);
代码快。