【问题标题】:Permutations example in ErlangErlang 中的排列示例
【发布时间】:2015-12-10 01:06:13
【问题描述】:

我有一个关于 Erlang Perms 实现的问题:

 perms([]) -> [[]];
 perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].

上面的代码来自一本名为Erlang Programming的书,看起来很简单,但运行良好。我感到困惑的是它是如何工作的。比如让我们用perms("12")这样的参数来运行它,那么如果我们分析递归的过程。我认为第一次返回的结果将类似于[[1|perms[2]-&gt;[[2]|[[]]]],这等于[[1|[[2]|[[]]]]。但它在 Erlang shell 中是错误的表达方式。

【问题讨论】:

    标签: erlang


    【解决方案1】:

    列表理解的一般行为是生成所有生成器的叉积(在应用定义的过滤器之后)。最好用一个例子来说明:

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

    在排列代码示例中,列表推导是这样执行的:

    H &lt;- L 是一个生成器,它将为输入列表 L 的每个术语生成一个值。在您的情况下,L = "12",它将生成两个术语字符 $1$2,并且它将使用第二个生成器的结果构建叉积:T &lt;- perms(L--[H])

    这里有一个非常聪明的东西,第二个生成器依赖于第一个,第一个生成器的每个元素将与第二个生成器自己的列表组合。所以$1 将与perms(L--[$1]) = perms("2") 生成的术语相结合

    如果您尝试评估perms("2"),同样的分析表明第一个生成器生成一个单独的术语$2perms([]) 结合

    最后一项计算为[[]],并将生成一个空列表。

    我们现在可以构建中间结果:[[H|T]] = [[$2|[]]] = [[$2]]

    此结果将生成单个术语 [$2]。所以顶级结果将是(考虑到所有生成的术语)[[$1|[$2]],[$2|[$1]] = [[$1,$2],[$2,$1]] = ["12","21"]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-03
      • 1970-01-01
      • 1970-01-01
      • 2013-10-22
      • 2015-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多