按每个顺序测试每个函数组合
Test every combination of functions in every order
我有一堆函数,a.process
,b.process
,c.process
...,我们称它们为a
,b
,c
...都以std::string
为参数并返回std::string
.
给定一个初始std::string s
,我想生成a
、b
、c
组合的所有可能输出。以任何顺序调用并给出s
作为初始输入。
例如,我想计算a(s)
、b(s)
、c(s)
、a(b(s))
、a(c(s))
、b(a(s))
、b(c(s))
、c(a(s))
、c(b(s))
、a(b(c(s)))
等。
我想我可以做一个函数来生成列表的每个排列,类似于 Python 的itertools.permutations
,但我这里有两个主要问题:
不仅想要每一个排列,我想要每个顺序的每一个排列。
更重要的是,我不知道如何将函数存储在数组中,就像在 Python 中一样
。
此外,我需要每个可能的输出都带有生成它的函数组合,因此对于我上面给出的示例,我知道输出按以下顺序排列:"a"
、"b"
、"c"
、"ab"
、"ac"
、"ba"
、"bc"
、"ca"
、"cb"
、"abc"
等。
我如何在C++中实现它?
要在数组中存储函数,需要使用函数指针。像这样的事情就可以了:
typedef string (*t_fnPtr)(string);
t_fnPtr fnPtrArray[10]; //Initialize this with your functions
然后,只需生成数组的所有组合并将其应用于字符串即可。看看这个问题。
我只是将 Sid 的答案充实到实际代码中。与Galik的答案不同,这不会产生重复
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using Fn = std::string (*)(std::string);
std::string apply_all(const std::vector<Fn>& fns, std::string s)
{
for(auto fn : fns)
s = fn(s);
return s;
}
int main()
{
std::string s = /* some string */;
std::vector<Fn> functions{/* initialize with functions */};
int n = functions.size();
for(int r = 1; r <= n; r++)
{
std::vector<bool> v(n);
std::fill(v.begin(), v.begin() + r, true); // select r functions
// permute through all possible selections of r functions
do {
std::vector<Fn> selected;
for(int i = 0; i < n; ++i)
if(v[i])
selected.push_back(functions[i]);
std::sort(selected.begin(), selected.end());
// permute through the r functions
do {
std::cout << apply_all(selected, s) << std::endl;
} while(std::next_permutation(selected.begin(), selected.end()));
} while(std::prev_permutation(v.begin(), v.end()));
}
}
现场示例
一些想法和伪代码
函数指针数组,每个函数一个。
typedef std::string (*Func)(std::string const&);
Func const func_array[] = {&a, &b, &c};
int const n = sizeof array / sizeof array[0]; // number of functions
我们需要
n choose 1 to get 1-element combinations a, b, c
n choose 2 to get 2-element combinations ab, ac, bc
n choose 3 to get 3-element combinations abc
此外,对于每个组合,我们需要所有可能的排列。
即For all k = 1 to n,
All permutations of (All combinations of n-choose-k)
素描
for i = 0 to 2^(n-1):
xi = elements of func_array corresponding to the '1' bits in i
used std::next_permutation() to generate all permutations of xi
查看 https://en.wikipedia.org/wiki/Power_set 和 http://en.cppreference.com/w/cpp/algorithm/next_permutation
如果我理解正确了这个问题,也许是这样的。它使用std::next_permutation
遍历进程的每个顺序,对于每个排序,它选择要(连续)对输入进行操作的每个子列表或进程:
std::string process_1(std::string const& s)
{ return s + 'a'; }
std::string process_2(std::string const& s)
{ return s + 'b'; }
std::string process_3(std::string const& s)
{ return s + 'c'; }
int main(int, char** argv)
{
using process = std::string(*)(std::string const&);
std::vector<process> processes;
processes.push_back(process_1);
processes.push_back(process_2);
processes.push_back(process_3);
std::vector<std::string> outputs;
std::sort(std::begin(processes), std::end(processes));
do
{
for(auto p = std::begin(processes); p != std::end(processes); ++p)
{
std::string s = "";
for(auto p1 = p; p1 != std::end(processes); ++p1)
s = (*p1)(s);
outputs.push_back(s);
}
}
while(std::next_permutation(std::begin(processes), std::end(processes)));
for(auto const& o: outputs)
std::cout << o << 'n';
}
输出:
abc
bc
c
acb
cb
b
bac
ac
c
bca
ca
a
cab
ab
b
cba
ba
a
注意:此方法似乎会产生一些重复项。应该有一种聪明的数学方法来消除它们,现在我无法消除它们,但您可以随时保持std::set<std::vector<process>>
来记录已经尝试过的每个组合,以确保没有重复。或者只是从输出中删除重复项。
- 可组合的lambda/std::函数与std::可选
- 我需要将多个函数组合为一个函数
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- C++组合函数总是产生 0
- 组合函数参数包和默认参数
- 我在C++中使用提升哈希函数将 3 个双精度组合成一个面临冲突的哈希
- uncrustify:如何将多行 C 函数调用的参数组合到一行上?
- 如何将这两个函数组合成一个实现?
- 如何将两个代码组合成一个函数?
- 如何组合lambda,vairadic函数和函数指针?
- 使用Set/Get-like方法或GetSet组合函数
- 找不到如何创建使用指针、字符和 for 函数组合的程序
- 使用参数包在C++中组合 lambda 函数
- 使用类/函数模板组合进行意外诊断
- 将 libstdc++ 和其他函数组合到一个库中
- 如何在组合函数中使用 boost::asio::d efer()
- 2个模板构造函数的组合构建与变异模板.如何
- 按每个顺序测试每个函数组合
- 组合 std::vector 默认值和填充构造函数
- 我可以在C++中动态组合函数和类型吗?