Erlang中列表的笛卡尔幂

时间:2012-11-05 22:47:17

标签: functional-programming erlang

我正在尝试将erlang Mastermind解算器编码为练习(我是一个完整的新手,但我认为这是一个功能性语言的有趣练习)

我希望它尽可能一般,所以我觉得我需要一个笛卡尔幂函数。类似的东西:

cart_pow([a,b],2) -> [[a,a],[a,b],[b,a],[b,b]]
cart_pow([a,b],3) -> [[a,a,a],[a,a,b],[a,b,a],[a,b,b],[b,a,a],[b,a,b],[b,b,a],[b,b,b]]

我想不出纯粹的功能(递归,地图,折叠......)解决方案。 有线索吗?奖金,如果它是懒惰的。

3 个答案:

答案 0 :(得分:3)

@ Ed'ka提供的解决方案简洁而且很好,但尽管如此,其复杂性为O(N)

我建议你考虑一下Exponentiation by squaring method,它在计算能力方面提供O(log(N))复杂性。使用这种技术,可以用这种方式实现笛卡尔幂:

%% Entry point
cart(List, N) ->
        Tmp = [[X] || X <- List],
        cart(Tmp, Tmp, N).

cart(_InitialList, CurrList, 1) ->
        CurrList;
cart(_InitialList, CurrList, N) when N rem 2 == 0 ->
        Tmp = mul(CurrList, CurrList),
        cart(Tmp, Tmp, N div 2);
cart(InitialList, CurrList, N) ->
        Tmp = cart(InitialList, CurrList, N - 1),
        mul(InitialList, Tmp).

mul(L1, L2) ->
        [X++Y || X <- L1, Y <- L2].

P.S。从shell(我将函数cart打包到mudule my_module)的用法示例:

1> c(my_module).
{ok,my_module}
2> 
2> my_module:cart([0,1], 2).
[[0,0],[0,1],[1,0],[1,1]]
3> 
3> my_module:cart([0,1], 3).
[[0,0,0],
 [0,0,1],
 [0,1,0],
 [0,1,1],
 [1,0,0],
 [1,0,1],
 [1,1,0],
 [1,1,1]]

答案 1 :(得分:2)

从Haskell实施:

cart_pow(Xs, N) -> 
    sequence(lists:duplicate(N, Xs)).

sequence([]) ->
    [[]];
sequence([Xs|Xss]) ->
    [[X|Xs1] || X <- Xs, Xs1 <- sequence(Xss)].

不确定如何使Erlang的列表变得懒惰。

<强>更新 通过简单地使尾递归(即使我相信这三者之间没有渐近的差异),可以在性能方面改进这个版本。

cart_pow(Xs, N) -> 
    sequence(lists:duplicate(N, Xs)).

sequence(Xss) ->
    sequence(Xss, [[]]).

sequence([], Acc) ->
    Acc;
sequence([Xs|Xss], Acc) ->
    sequence(Xss, [[X|Xs1] || X <- Xs, Xs1 <- Acc]).

与@ stemm的版本相比:

1> timer:tc(fun() -> length(tmp1:cart([0,1], 20)) end).
{383939,1048576}
2> timer:tc(fun() -> length(tmp1:cart_pow([0,1], 20)) end).
{163932,1048576}

PS:甚至更好:

sequence(Xss) ->
    lists:foldl(fun(Xs, A) -> [[X|Xs1] || X <- Xs, Xs1 <- A] end, [[]], Xss).

答案 2 :(得分:1)

您可能会发现此Stack Overflow问题很有用,它涉及在函数式语言中生成列表的笛卡尔幂。问题针对F#,但评论中也有一个Haskell示例:F#: how to find Cartesian power