找到所有可能的配对

3

我正在编写一些Erlang代码,并希望创建一个递归函数,从列表中提取所有可能的配对。该列表可能没有元素,但最多可以有70个元素。为所有这些情况编写案例是不好的做法,我需要您的帮助。

pair(List) ->
    case List of
        []              -> [];
        [A]             -> [{A}];
        [A, B]          -> [{A, B}, {B, A}];
        [A, B, C]       -> [{A, B}, {A, C}, {B, A}, {B, C}, {C, A}, {C, B}];
    end.

我发现了一个用于创建所有可能组合(不仅仅是所有对)列表的函数,但我不知道如何修改它。
combos(1, L) -> [[X] || X <-L];
combos(K, L) when K == length(L) -> [L];
combos(K, [H|T]) ->
    [[H | Subcombos] || Subcombos <- combos(K-1, T)]
    ++(combos(K, T)).

combos(L) ->
    lists:foldl(
        fun(K, Acc) -> Acc++(combos(K, L)) end,
        [[]], lists:seq(1, length(L))).
1个回答

5

您可以使用列表推导式并将同一列表两次引用为输入:

1> L = [a,b,c,d].
[a,b,c,d]
2> [{X, Y} || X <- L, Y <- L].
[{a,a},
 {a,b},
 {a,c},
 {a,d},
 {b,a},
 {b,b},
 {b,c},
 {b,d},
 {c,a},
 {c,b},
 {c,c},
 {c,d},
 {d,a},
 {d,b},
 {d,c},
 {d,d}]

如果有更清晰或更有效的方法来做这件事,我会感到惊讶。

编辑

如果您不想要相同的对({a,a}等),您可以添加一个保护条件以确保它们不相等:

5> [{X, Y} || X <- L1, Y <- L1, X /= Y]. 
[{a,b},
 {a,c},
 {a,d},
 {b,a},
 {b,c},
 {b,d},
 {c,a},
 {c,b},
 {c,d},
 {d,a},
 {d,b},
 {d,c}]

谢谢!这正是我想要的,除了具有相同变量的对(即 {a, a},{b, b} 等)。在列表推导式中是否有使用 guards 的方法? - Oscar
1
@Oscar 当然,在结尾添加一个保障不等式的守卫就可以解决问题。 - zxq9

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接