こいつをC++で書いたもの。
糞汚いコードだがとりあえずMSVCで動いた。
# include "stdafx.h"
# include <functional>
# include <boost/coroutine/all.hpp>
# include <iostream>
# include <iterator>
# include <numeric>
# include <algorithm>
# include <vector>
# include <boost/bind.hpp>
template<typename T>
void iter_permutations(typename boost::coroutines::coroutine<std::vector<T>()>::caller_type& yield, std::vector<T> pool){
const size_t n = pool.size();
const size_t r = n;
if(r > n)return;
std::vector<size_t> indices(n);
std::iota(indices.begin(), indices.end(), 0);
std::vector<size_t> cycles(r);
std::iota(cycles.begin(), cycles.end(), n-r+1);
std::reverse(cycles.begin(), cycles.end());
{
std::vector<T> ret(r);
ret.assign(pool.begin(), pool.begin()+r);
yield(ret);
}
while(n){
auto fl = true;
for(int i = r - 1; i >= 0 ; --i){
cycles[i] -= 1;
if(cycles[i] == 0){
std::vector<size_t>::iterator tmp = indices.begin();
std::advance(tmp, i);
auto tmp_val = *tmp;
indices.erase(tmp);
indices.push_back(tmp_val);
cycles[i] = n - i;
}else{
auto j = cycles[i];
auto k = n - j;
boost::swap(indices[i], indices[k]);
{
std::vector<T> ret(r);
for(size_t m = 0; m < r; ++m){
ret[m] = pool[indices[m]];
}
yield(ret);
}
fl = false;
break;
}
}
if(fl){
break;
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
vector<int> a(3);
iota(a.begin(), a.end(), 0);
boost::coroutines::coroutine<std::vector<int>()> mycol(boost::bind(iter_permutations<int>, _1, a));
while(mycol){
auto b = mycol.get();
copy(b.begin(), b.end(), ostream_iterator<int>(cout, ","));
cout << endl;
mycol();
}
return 0;
}