文件夹:折叠方法

时间:2014-03-11 13:23:41

标签: java algorithm generics

我在Java中遇到了一个问题,我遇到了以下接口。

public interface Function2<T, U, R>
{
    R apply(T t, U u);
}

public interface Folder<T, U>
{
    U fold(U u, Queue<T> list, Function2<T,U,U> function);
}

并且问题需要开发人员实施:

public class MyFolder<T, U> implements Folder<T, U>
{
    public U fold(U u, Queue<T> ts, Function2<T, U, U> function)
    {
        if(u == null || ts == null || function == null)
            throw new IllegalArgumentException();

        if (ts.isEmpty()) {
            return u;
        }

        // The recursive implementation will overflow the stack for
        // any data set of real size, your job is to implement a
        // non-recursive solution
        //return fold(function.apply(ts.poll(), u), ts, function);
        return null;
    }
}

有人可以向我解释折叠功能的作用吗?我似乎无法在网上找到例子。我已阅读here关于此方法的用途,但未提供任何具体示例。

3 个答案:

答案 0 :(得分:2)

来自维基百科:

在函数式编程中,fold-也称为reduce,accumulate,aggregate,compress或inject - 指的是一系列高阶函数,它们分析递归数据结构并通过使用给定的组合操作重新组合结果递归处理其组成部分,建立一个返回值。通常,向折叠呈现组合函数,数据结构的顶部节点,以及可能在某些条件下使用的一些默认值。然后折叠继续使用系统方式的功能组合数据结构层次结构的元素。

http://en.wikipedia.org/wiki/Fold_%28higher-order_function%29

哦,评论中实现的非递归等价物是:

do {
    u = function.apply(ts.poll(), u);
} while (!ts.isEmpty());
return u;

答案 1 :(得分:2)

Fold递归地将函数应用于每个元素,给出的代码如下:

public interface Function2<T, U, R>
{
    R apply(T t, U u);
}

public interface Folder<T, U>
{
    U fold(U u, Queue<T> list, Function2<T,U,U> function);
}
public static class MyFolder<T, U> implements Folder<T, U>
{
    public U fold(U u, Queue<T> ts, Function2<T, U, U> function)
    {
        if(u == null || ts == null || function == null)
            throw new IllegalArgumentException();

        if (ts.isEmpty()) {
            return u;
        }

        return fold(function.apply(ts.poll(), u), ts, function);
    }
}

public static void main(String[] args) {
    Folder<Integer,Integer> fold = new MyFolder<Integer, Integer>();
    Queue<Integer> queue = new LinkedList<Integer>();
    queue.add(1);
    queue.add(2);
    queue.add(3);

    Integer result = fold.fold(0, queue, new Function2<Integer, Integer, Integer>() {
        public Integer apply(Integer a, Integer b) {
            return a + b;
        }
    });
    System.out.println(result);
}

哪个输出

6

迭代解决方案看起来应该是这样的:

public U fold(U u, Queue<T> ts, Function2<T, U, U> function)
{
    if(u == null || ts == null || function == null)
        throw new IllegalArgumentException();

    if (ts.isEmpty()) {
        return u;
    }

    T item = null;

    while ((item = ts.poll()) != null) {
        u = function.apply(item, u);
    }
    return u;
}

答案 2 :(得分:0)

例如,fold(0,{1,2,3,4,5},+)应该提供0+1+2+3+4+5 = 15