Need to cacl factorial of all numbers from 1 to k and save them in mpl container using boost/mpl.
Range of this nums storaged in range_c. The difficulty is that I have to storage all previous values: k! = (k-1)!*k
k! = (k-1)!*k
I thought that I will storage previous values in mpl::vector_c, ie each iteration I will take value from source range_c and multiplie it with previous value (k-1)!
which contains in vector_c, but I have a lot of mistakes in this code:
namespace mpl = boost::mpl;
const int border = 10;
using namespace mpl;
typedef
range_c <int, 1, border>
Numbers;
typedef vector_c<int, 1> data;
typedef
mpl::transform
<
Numbers,
data,
push_back<data, multiplies <_, _>>,
back_inserter
<
mpl::vector <>
>
>::type
Factorials;
In all implementations factorial was calculated for each number from 1. In the task i need to calc each next factorial by multiplication with previous factorial. Here right code:
namespace mpl = boost::mpl;
using namespace mpl;
const int border = 15;
typedef range_c<int, 1, border> nums;
typedef vector<int_<1>> data;
typedef mpl::fold<
nums, data,
mpl::push_back<_1, mpl::multiplies<_2, back<_1>>>
>::type Factorials;
You may use the following:
namespace detail
{
// General computation of factorial
template <std::size_t N>
struct factorial :
std::integral_constant<std::size_t, N * factorial<N - 1>::value>
{
};
// special case for 0
template <>
struct factorial<0> : std::integral_constant<std::size_t, 1u>
{};
// helper to create the sequence of factorial value
template <typename T> struct factorial_seq_impl;
template <std::size_t...Is>
struct factorial_seq_impl<std::index_sequence<Is...>>{
using type = std::index_sequence<factorial<Is>::value...>;
};
}
// And finally
template <std::size_t N>
using factorial_seq =
typename detail::factorial_seq_impl<std::make_index_sequence<N>>::type;
static_assert(std::is_same<std::index_sequence<1, 1, 2, 6, 24>, factorial_seq<5>>::value, "");
A factorial mpl version and a collection of first 10 results in a vector:
template <typename current, typename to, typename result>
struct calc :
eval_if< less_equal< current, to >,
calc< typename current::next, to, typename multiplies< result, current > >,
result
>::type
{};
template<typename value>
struct factorial :
calc<int_<1>, value, int_<1> >::type
{};
template <>
struct factorial<int_<0> > :
int_<1>::type
{};
template <>
struct factorial<int_<1> > :
int_<1>::type
{};
template <int value>
struct factorial_c :
factorial<int_<value> >::type
{};
struct factorial_collection_10 :
transform<
range_c<int, 0, 10>,
factorial<boost::mpl::_1>,
back_inserter<vector0<> >
>::type
{};
Test code:
int main()
{
// get 5! value
std::cout << "5! = " << factorial_c<5>::value << std::endl;
// access 6th element of the factorial collection
std::cout << "6! = " << at<factorial_collection_10, int_<6> >::type::value << std::endl;
// copy factorial collection to std vector to check values at runtime
std::vector<int> factorialVec;
for_each< factorial_collection_10, boost::mpl::_1 >(boost::bind(static_cast<void(std::vector<int>::*)(const int&)>(&std::vector<int>::push_back), &factorialVec, boost::lambda::_1));
std::cout << "First 10 factorial numbers: " << std::endl;
for (std::size_t x = 0; x < factorialVec.size(); ++x)
std::cout << x << "! = " << factorialVec[x] << std::endl;
return 0;
}
Output:
5! = 120
6! = 720
First 10 factorial numbers:
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.