递归算法,主要考虑两点,一是自己调用自己,二是调用自己终止的条件是什么
1. 用递归实现N的阶乘
调用函数自身终止的条件 :当到1的时候,就不在调用自身了。
示例如下
/**
* N的阶乘,递归实现
*
* @param n
* @return
*/
public static int diGui_JieCheng(int n) {
if (n == 1) {
return 1;
} else {
int num = n * diGui_JieCheng(n - 1);
return num;
}
}
2. 用递归实现从1加到N的和
调用函数自身终止的条件 :当到1的时候,就不在调用自身了。或着当数据加到N时停止
/**
* 从1加到n,用递归算法实现
*
* @param n
* @return
*/
public static int diGui_1_N(int n) {
if (n == 1) {
return 1;
} else {
int num = n + diGui_1_N(n - 1);
return num;
}
}
3.JAVA8的流对递归支持
主要涉及到的两个函数:
- Stream#generate(Supplier) :
返回无限顺序无序流,其中每个元素由提供的Supplier生成。 这适用于生成恒定流,随机元素流等。- Stream#iterate(Object, UnaryOperator):
返回有序无限连续Stream由函数的迭代应用产生f至初始元素seed ,产生Stream包括seed , f(seed) , f(f(seed)) ,等
第一元件(位置0在) Stream将是提供seed 。 对于n > 0 ,位置n的元素将是将函数f应用于位置n - 1的元素的n - 1 。
简单的说就是指定一个常量seed,产生从seed到常量f(由UnaryOperator返回的值得到)的流。这是一个迭代的过程。
3.1 计算1的平方到n的平方的和,取前5个值
- 第一种实现方式
public class StreamGenerate {
public static void main(String[] args) {
// 1.请计算1的平方到n的平方的和,取前5个值
Stream.iterate(new Pair(1, 1),
pair -> new Pair(pair.index + 1, Math.pow(pair.index + 1, 2)))
.limit(5)
.map(pair -> pair.value)
.collect(Collectors.toList())
.forEach(System.out::println);
}
}
/**
* 内部类,记录数字和数字的平方
* @param index 数字
* @param value 数字的平方
*/
class Pair {
public final int index;
public final double value;
public Pair(int index, double value) {
this.index = index;
this.value = value;
}
}
上面的方法是把lambda表达式写在了方法内,我们可以根据递归的终止条件进一步优化类,改进版本如下
- 第二种方式的实现(改进第一种实现的方式)
public class StreamGenerate {
public static void main(String[] args) {
Stream.iterate(Pair2.SEED, Pair2::next)
.limit(5)
.map(pair2 -> pair2.value)
.collect(Collectors.toList())
.forEach(System.out::println);
}
}
/**
* 内部类,记录数字和数字的平方
* @param index 数字
* @param value 数字的平方
*/
class Pair2 {
public static final Pair2 SEED = new Pair2(1, 1);
public final int index;
public final double value;
public Pair2(int index, double value) {
this.index = index;
this.value = value;
}
public Pair2 next() {
return new Pair2(index + 1, Math.pow(index + 1, 2));
}
}
3.2 阶乘函数
public class StreamGenerate {
public static void main(String[] args) {
// 3. 阶乘函数
System.out.println("阶乘函数");
Stream.iterate(Factorial.SEED, Factorial::next)
.limit(5)
.map(factorial -> factorial.value)
.collect(Collectors.toList())
.forEach(System.out::println);
}
}
class Factorial {
public static final Factorial SEED = new Factorial(1, 1);
public final int index;
public final int value;
public Factorial(int index, int value) {
this.index = index;
this.value = value;
}
public Factorial next() {
return new Factorial(index + 1, value * index);
}
}
3.3 斐波那契函数
1,2,3,5,8,13,21,33…
public class StreamGenerate {
public static void main(String[] args) {
// 4. 斐波那契
System.out.println("斐波那契");
Stream.iterate(Fibonacci.SEED, Fibonacci::next)
.limit(5)
.map(fibonacci -> fibonacci.value)
.collect(Collectors.toList())
.forEach(System.out::println);
}
}
class Fibonacci {
public static final Fibonacci SEED = new Fibonacci(1, 1);
public final int previous;
public final int value;
public Fibonacci(int previous, int value) {
this.previous = previous;
this.value = value;
}
public Fibonacci next() {
return new Fibonacci(value, value + previous);
}
}