7.4. 编写更复杂的递归函数
某些递归函数只有一个基本情况和一次递归调用。但通常存在多于一个基本情况或一次递归调用,或者两者皆有。
以下是递归函数的通用结构。
if ( base case 1 )
// return some simple expression
else if ( base case 2 )
// return some simple expression
else if ( base case 3 )
// return some simple expression
else if ( recursive case 1 ) {
// some work before
// recursive call
// some work after
}
else if ( recursive case 2 ) {
// some work before
// recursive call
// some work after
}
else { // recursive case 3
// some work before
// recursive call
// some work after
}
Example 7.4.1
考虑一个相对简单的函数,用于判断整数 X 是否为素数。 Y 是一个辅助变量,用作除数。在最初调用该函数时, Y = X - 1
boolean prime ( int x , int y ) {
if ( y == 1 )
return true ;
else if ( x % y == 0 )
return false ;
else
return prime ( x , y -1 );
}
boolean prime ( int x , int y ) {
if ( y == 1 )
return true ;
else if ( x % y == 0 )
return false ;
else
return prime ( x , y - 1 );
}
我们看到, Prime 有两个基本情况和一个递归调用。
Example 7.4.2
这里有一个具有多个递归调用的函数。给定一个名为 set 的 int 数组,函数 isSubsetSum 确定 set 中的某些值相加是否等于 sum 。例如,给定数字 3、8、1、7 和 -3,在 sum = 4 下,结果是 true ,因为值 3 和 1 相加得到 4。如果 sum = 6 ,那么结果将是 true ,因为 \(8 + 1 + -3 = 6\) 。另一方面,如果 sum = 2 ,那么结果是 false ,因为没有五个数字的组合相加等于 2。在此代码中,变量 n 是我们查看的值数量。我们不想仅仅使用 set.length ,因为递归调用需要限制它们的工作范围在数组的一部分。
boolean isSubsetSum ( int set [], int n , int sum ) {
if ( sum == 0 )
return true ;
if (( n == 0 ) && ( sum != 0 ))
return false ;
return isSubsetSum ( set , n - 1 , sum ) || isSubsetSum ( set , n - 1 , sum - set [ n - 1 ]);
}
boolean isSubsetSum ( int set [] , int n , int sum ) {
if ( sum == 0 )
return true ;
if (( n == 0 ) && ( sum != 0 ))
return false ;
return isSubsetSum ( set , n - 1 , sum ) || isSubsetSum ( set , n - 1 , sum - set [ n - 1 ] );
}
本例有两个基本情况和两个递归调用。
Example 7.4.3
此处有一个函数,它包含多个基本情况和多个递归调用。函数 paths 计算达到给定篮球得分的不同方法数量。回想一下,在篮球中,得分可以以 1、2 或 3 分的增量获得。因此,如果 n = 3 ,则 paths 将返回 4,因为累积 3 分有四种不同的方法: \(1+1+1, 1+2, 2+1,\) 和 3。
int paths ( int n ) {
if ( n == 1 )
return 1 ;
if ( n == 2 )
return 2 ;
if ( n == 3 )
return 4 ;
return paths ( n - 1 ) + paths ( n - 2 ) + paths ( n - 3 );
}
int paths ( int n ) {
if ( n == 1 )
return 1 ;
if ( n == 2 )
return 2 ;
if ( n == 3 )
return 4 ;
return paths ( n - 1 ) + paths ( n - 2 ) + paths ( n - 3 );
}
该函数具有三个基本情况和三个递归调用。