Erlang尾递归

再一次被鄙视了。是不是被鄙视的次数多了就不会有感觉了。

被问到了Erlang,没有循环结构【傻缺的设计】,怎么计算一个数组的和呢。

这个用递归可以解决,那么接下来一个问题让人头痛。

递归是可以解决,那么,如果递归深度很深,栈就爆掉了。请问如何优化呢?

这个真没了解过。

回来查了一下,Erlang中有一个叫做“尾递归”的概念,编译器会帮忙把尾递归优化成一个循环结构,这就是为什么Erlang敢不设计循环结构的原因所在。

看下面代码:

package zoer;

public class TestBitSet {

	public static void main(String[] args) {
		int d[] = { 4, 7, 1, 9, 3 };
		sum2(d, 5, 4);
		System.out.println(SUM_);
	}

	/**
	 * 从第一个元素加到最后一个元素
	 * 
	 * @param data
	 * @param count
	 * @param i
	 * @return
	 */
	public static int sum(int data[], int count, int i) {
		if (i == count - 1) {
			return data[i];
		}
		return data[i] + sum(data, count, i + 1);
	}

	/**
	 * 从最后一个元素加到第一个元素
	 * 
	 * @param data
	 * @param count
	 * @param i
	 * @return
	 */

	static int SUM_ = 0;

	public static void sum2(int data[], int count, int i) {
		SUM_ += data[i];
		if (i == 0) {
			return;
		}
		sum2(data, count, i - 1);
	}
}

代码中两个函数都实现了求和操作,递归操作都在函数的最后进行。那么如果在Erlang中,哪个更好呢?

答案是第二个。因为第二个函数在sum2返回之后,没有再做其他任何操作。所以这层递归进入栈是没有意义的。Erlang把这层优化掉了。

在sum函数中,return data[i] + sum(data, count, i + 1);实际上在递归返回之后又做了一个加法操作,这让递归返回变的有意义,所以Erlang不会做这一层次的优化。

你可能感兴趣的:(Erlang尾递归)