我有很多功能,a.process
,b.process
,c.process
...,让他们称呼a
,b
, c
...所有人都以std::string
为参数并返回std::string
。
给定一个初始std::string s
,我想生成a
,b
,c
...组合的所有可能输出...按任意顺序调用并给出{{ 1}}作为初始输入。
例如,我想计算s
,a(s)
,b(s)
,c(s)
,a(b(s))
,a(c(s))
,{{1 }},b(a(s))
,b(c(s))
,c(a(s))
等
我想我可以创建一个函数来生成列表的每个排列,比如Python c(b(s))
,但我有两个主要问题:
我不想要每一个排列,我想要每个顺序的每一个排列。
更重要的是,我不知道如何将函数存储在数组中,就像在Python中一样。
此外,我需要每个可能的输出都带有生成它的函数组合,因此对于上面给出的示例,我知道输出按以下顺序排列:a(b(c(s)))
,itertools.permutations
, "a"
,"b"
,"c"
,"ab"
,"ac"
,"ba"
,"bc"
,"ca"
等。
我怎样才能在C ++中实现它?
答案 0 :(得分:1)
要在数组中存储函数,您需要使用function pointers。这样的事情可以做到:
typedef string (*t_fnPtr)(string);
t_fnPtr fnPtrArray[10]; //Initialize this with your functions
然后,只需生成数组的所有组合并将其应用于字符串即可。请看this question。
答案 1 :(得分:1)
我只是将Sid's answer充实到实际代码中。与Galik's answer不同,这不会产生重复
#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()));
}
}
答案 2 :(得分:0)
一些想法和伪代码
函数指针数组,每个函数一个。
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
答案 3 :(得分:0)
如果我已经理解了这个问题,可能是这样的。它使用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>>
来记录已经尝试过的所有组合,以确保没有重复。或者只是从输出中删除重复项。