查找字符串向量的 r 组合
Finding r-Combinations of a Vector of Strings
我正在尝试生成给定字符串列表的所有可能的 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路线,但这给了我重复(我正在寻找组合,而不是排列......所以在上面的例子中,集合(黄色、蓝色(之后,(蓝色、黄色(不应该包括在内(。
您可以使用如下所示的内容:
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( 创建一系列 3 位。
2( 由于r
是 2,将最右边的两个位初始化为 1。
3(输出向量中与on位对应的项,例如,如果bitarray[0]
为1,则输出original[0]
,如果bitarray[1]
为1,则输出original[1]
等。
4( 调用位上的next_permutation()
以获取"下一个"位模式。
重复步骤 3 和 4,直到false
next_permutation(( 。
所以基本上,你需要一个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]
是"真实的"。
调用next_permutation
,位数组更改: 110
输出original[0]
和original[1]
。
如果再次调用,next_permutation
将返回 false,因为没有更多的排列。
做。
我的解决方案,比使用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;
});
}
在此处查找for_each_combination
。
输出:
{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);
而且代码很快。
- 检查向量是否具有所有可能的字符组合
- 从向量的向量中删除向量的组合
- 如何得到几个子向量的组合
- 如何组合两个整数向量
- 如果我们从每个 Y 向量中选择一个值,则 X 数字的每个组合都可能
- 在不使用递归的情况下求解所有 2D 字符串向量组合?(C++)
- 字符串向量的有效组合
- 向量的高效组合最小值和平均值计算
- 如何在 Boost.Sprit.Qi 中从向量制作组合的 ascii::string 规则<string>?
- 将多个向量(函数结果)组合到一个使用模板中
- 双重释放或损坏(输出):使用向量的组合算法0x0000000001a880a0***
- 如何沿行组合两个向量?
- 创建多个向量的所有可能组合
- 如何在 c++ 中将集合和数组合并到向量中
- 在C++编程语言中,如何用n个向量长度的所有可能的字符串组合来填充向量
- 在 C++11 中计算字母和单词的双字母组合的 std::线程向量的问题
- 找到两个向量数组的组合,该数组的总和是 c++ 中所有其他组合的最大值
- 如何在C++中组合向量的元素
- c++组合向量(如果它们共享一个数字)
- 这是用组合向量类重载[]的正确方法吗?