明日はコンピュータ サイエンスの中間試験があり、これらの再帰関数の複雑さを判断するのに助けが必要です。簡単なケースの解決方法はわかっていますが、これらの難しいケースの解決方法をまだ学ぼうとしています。これらは、私が理解できなかった例題のほんの一部です。どんな助けでも大歓迎ですし、勉強に大いに役立ちます。ありがとうございます。
int recursiveFun1(int n)
{
if (n <= 0)
return 1;
else
return 1 + recursiveFun1(n-1);
}
int recursiveFun2(int n)
{
if (n <= 0)
return 1;
else
return 1 + recursiveFun2(n-5);
}
int recursiveFun3(int n)
{
if (n <= 0)
return 1;
else
return 1 + recursiveFun3(n/5);
}
void recursiveFun4(int n, int m, int o)
{
if (n <= 0)
{
printf("%d, %d\n",m, o);
}
else
{
recursiveFun4(n-1, m+1, o);
recursiveFun4(n-1, m, o+1);
}
}
int recursiveFun5(int n)
{
for (i = 0; i < n; i += 2) {
// do something
}
if (n <= 0)
return 1;
else
return 1 + recursiveFun5(n-5);
}
ベストアンサー1
各関数の時間計算量(Big O 表記):
int recursiveFun1(int n)
{
if (n <= 0)
return 1;
else
return 1 + recursiveFun1(n-1);
}
この関数は、基本ケースに到達する前に n 回再帰的に呼び出されるため、その は線形O(n)
と呼ばれることがよくあります。
int recursiveFun2(int n)
{
if (n <= 0)
return 1;
else
return 1 + recursiveFun2(n-5);
}
この関数は n-5 回呼び出されるので、関数を呼び出す前に n から 5 を減算しますが、n-5 も ですO(n)
。(実際には n/5 回順に呼び出されます。そして、O(n/5) = O(n) です)。
int recursiveFun3(int n)
{
if (n <= 0)
return 1;
else
return 1 + recursiveFun3(n/5);
}
この関数は 5 を底とする log(n) です。関数を呼び出す前に毎回 5 で割るため、O(log(n))
(底 5) は対数と呼ばれることが多く、ほとんどの場合 Big O 表記法と複雑性分析では底 2 が使用されます。
void recursiveFun4(int n, int m, int o)
{
if (n <= 0)
{
printf("%d, %d\n",m, o);
}
else
{
recursiveFun4(n-1, m+1, o);
recursiveFun4(n-1, m, o+1);
}
}
ここでは、各関数呼び出しはn回再帰されない限り、それ自体を 2 回呼び出すため、O(2^n)
、つまり指数 になります。
int recursiveFun5(int n)
{
for (i = 0; i < n; i += 2) {
// do something
}
if (n <= 0)
return 1;
else
return 1 + recursiveFun5(n-5);
}
ここで、forループは2ずつ増加しているのでn/2かかり、再帰はn/5かかり、forループは再帰的に呼び出されるので、時間計算量は
(n/5) * (n/2) = n^2/10、
漸近的な動作と最悪のシナリオの考慮、またはビッグ O が目指す上限により、最大の項のみに関心があるため、 となりますO(n^2)
。
中間試験頑張ってください ;)