[英]Pascal Triangle Recursive Program optimization in C++
I have built recursive function to compute Pascal's triangle values. 我已经建立了递归函数来计算Pascal的三角形值。
Is there a way to optimize it? 有没有办法优化它?
Short reminder about Pascal's triangle: C(n, k) = C(n-1, k-1) + C(n-1, k) My code is: 关于Pascal三角形的简短提醒:C(n,k)= C(n-1,k-1)+ C(n-1,k)我的代码是:
int Pascal(int n, int k) {
if (k == 0) return 1;
if (n == 0) return 0;
return Pascal(n - 1, k - 1) + Pascal(n - 1, k);
}
The inefficiency I see is that it stores some values twice. 我看到的低效率是它存储了两次值。 Example: C(6,2) = C(5,1) + C(5,2) C(6,2) = C(4,0) + C(4,1) + C(4,1) + C(4,2) it will call C(4,1) twice
例:C(6,2)= C(5,1)+ C(5,2)C(6,2)= C(4,0)+ C(4,1)+ C(4,1)+ C(4,2)它将调用C(4,1)两次
Any idea how to optimize this function? 知道如何优化这个功能吗?
Thanks 谢谢
The following routine will compute the n-choose-k, using the recursive definition and memoization. 以下例程将使用递归定义和memoization计算n-choose-k。 The routine is extremely fast and accurate:
例行程序非常快速准确:
inline unsigned long long n_choose_k(const unsigned long long& n,
const unsigned long long& k)
{
if (n < k) return 0;
if (0 == n) return 0;
if (0 == k) return 1;
if (n == k) return 1;
if (1 == k) return n;
typedef unsigned long long value_type;
class n_choose_k_impl
{
public:
n_choose_k_impl(value_type* table,const value_type& dimension)
: table_(table),
dimension_(dimension / 2)
{}
inline value_type& lookup(const value_type& n, const value_type& k)
{
const std::size_t difference = static_cast<std::size_t>(n - k);
return table_[static_cast<std::size_t>((dimension_ * n) + ((k < difference) ? k : difference))];
}
inline value_type compute(const value_type& n, const value_type& k)
{
// n-Choose-k = (n-1)-Choose-(k-1) + (n-1)-Choose-k
if ((0 == k) || (k == n))
return 1;
value_type v1 = lookup(n - 1,k - 1);
if (0 == v1)
v1 = lookup(n - 1,k - 1) = compute(n - 1,k - 1);
value_type v2 = lookup(n - 1,k);
if (0 == v2)
v2 = lookup(n - 1,k) = compute(n - 1,k);
return v1 + v2;
}
value_type* table_;
const value_type dimension_;
};
static const std::size_t static_table_dim = 100;
static const std::size_t static_table_size = static_cast<std::size_t>((static_table_dim * static_table_dim) / 2);
static value_type static_table[static_table_size];
static bool static_table_initialized = false;
if (!static_table_initialized && (n <= static_table_dim))
{
std::fill_n(static_table,static_table_size,0);
static_table_initialized = true;
}
const std::size_t table_size = static_cast<std::size_t>(n * (n / 2) + (n & 1));
unsigned long long dimension = static_table_dim;
value_type* table = 0;
if (table_size <= static_table_size)
table = static_table;
else
{
dimension = n;
table = new value_type[table_size];
std::fill_n(table,table_size,0LL);
}
value_type result = n_choose_k_impl(table,dimension).compute(n,k);
if (table != static_table)
delete [] table;
return result;
}
Keep a table of previously returned results (indexed by their n
and k
values); 保留一张先前返回结果的表格(以
n
和k
值为索引); the technique used there is memoization . 那里使用的技术是memoization 。 You can also change the recursion to an iteration and use dynamic programming to fill in an array containing the triangle for
n
and k
values smaller than the one you are trying to evaluate, then just get one element from it. 您还可以将递归更改为迭代,并使用动态编程来填充包含三角形的数组,其中
n
和k
值小于您要评估的值,然后从中获取一个元素。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.