递归的几种常用示例算法,及JAVA8 Lambda对递归的支持


递归算法,主要考虑两点,一是自己调用自己,二是调用自己终止的条件是什么

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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值