我很难将函数从递归转换为非递归 使用MPIR的库变量“mpz_t”而不是“unsigned __int64”的函数。我也在考虑如何编写循环。当我把它递归时,它很容易,但是当我试图使它非递归时,很难!
unsigned __int64 exampleFunc( unsigned __int64 a,
unsigned __int64 b,
unsigned __int64 c )
{
if( a <= 2 )
return a + 1;
if( b <= 4 )
return b;
if( c == 3 )
return c - 1;
if( b == 5 )
c += 2;
// How will I put these into a loop?
return exampleFunc( a - 1, b - 2, c ) + exampleFunc( 0, b + 1, c - 1 );
};
部分问题是我们无法编写一个返回mpz_t值的函数。 我们只能写一个值(就像一个指针)。所以,这样的事情 不会起作用:
mpz_t exampleFunc( ... );
这意味着,这样的事情可以起作用:
void exampleFunc( mpz_t out, ... );
甚至是全局变量(不强烈推荐):
mpz_t g_out;
mpz_init( g_out );
void exampleFunc( ... ) { g_out = ? };
注意:
我们应该尽量不使用数组甚至是向量,因为数字会非常大 - 这就解释了为什么我从无符号__int64切换到mpz_t。除非我们真的需要......
请帮助,我真的很强调。感谢。
答案 0 :(得分:1)
关于gmp的问题:尝试使用gmpxx.h - 你可以像返回一个整数那样返回mpz_class
对象。
mpz_class withgmp( const mpz_class &a, const mpz_class &b, mpz_class c )
{
if( a <= 2 )
return a + 1;
if( b <= 4 )
return b;
if( c == 3 )
return c - 1;
if( b == 5 )
c += 2;
return withgmp( a - 1, b - 2, c ) + withgmp( 0, b + 1, c - 1 );
}
请注意,我按值传递c
,因为它可能在函数中被修改。
或者,如果必须使用普通C,则应该为结果传递第四个参数,如下所示:
void withmpz( mpz_t a, mpz_t b, mpz_t c, mpz_t result)
{
// ... leaving out the boundary conditions
mpz_t left; mpz_init(left);
// ... leaving out code for adjusting a,b and c
withmpz(a,b,c, left);
mpz_t rightt; mpz_init(right);
// ... leaving out code for adjusting a,b and c
withmpz(a,b,c, right);
mpz_add(result, left, right);
}
请注意mpz_t看起来好像是按值传递,但实际上它总是通过引用传递,所以a,b,c在调用withmpz
之后会发生变化
问题的第二部分,如何将其转换为迭代,确实更难。一种方法是将其更改为基于堆栈的算法,其中每个迭代步骤用需要添加的2个值替换堆栈的顶部,直到可以立即计算一个,然后将其添加到最终结果,重复此直到堆叠中没有更多值。
答案 1 :(得分:0)
指向指针的指针可能是解决方案:您通过值传递指针指针并根据需要修改指针和指向的数据