erlang - 如果子列表检查失败,列表理解停止生成某些列表
问题描述
我有一个代码,它通过重复生成所有可能的变化(长度为 N)。
variation(1, L) ->
[ [H] || H <- L ];
variation(N, L) ->
[[H | T] || H <- L, T <- variation(N - 1, L)].
对于variation(3, [1,2,3,4]),它将生成:
[[1,1,1,1],[1,1,1,2],[1,1,1,3],[1,1,1,4],[1,1,2,1] ……]
我想在列表生成过程中检查一个条件。如果子列表失败,它应该停止生成从某个子列表开始的列表。例如,如果 [1,1] 子列表未能满足该条件(检查),则它不应生成 [1,1,1,1]、[1,1,1,2] 等(所有以 [1 ,1])。
我不知道它是否可能与 1 列表理解。到目前为止,我有这个代码:
variation(1, L) ->
[ [H] || H <- L ];
variation(N, L) ->
[[H | T] || H <- L, T <- variation(N - 1, L), check([H|T]) ].
这个解决方案只会返回那些不会失败的列表(它有效,但对于大输入来说真的很慢)。
如果 [1,1] 失败,它将尝试生成 [1,1,1,2],但这些也会导致检查失败。我需要一个解决方案,它不会尝试生成以 [1,1,...] 开头的列表(或以前失败的子列表)。
解决方案
首先是一个小细节:根据您的问题,variations(3, [1,2,3]).
应该生成[[1,1,1,1], [1,1,1,2], …]
但它实际上会生成[[1,1,1], [1,1,2], …]
. 我会假设代码是正确的,你的意思是说variations(4, [1,2,3]).
应该生成[[1,1,1,1], [1,1,1,2], …]
我编写了您的函数的另一个版本,在 LC 右侧使用不同的顺序,避免在使用以下命令检查其前缀已经为假时生成列表check/1
:
variation(1, L) ->
[ [Elem] || Elem <- L ];
variation(N, L) ->
[ Init ++ [Last] || Init <- variation(N-1, L), check(Init), Last <- L].
如您所见,因为check(Init)
发生在 之前 Last <- L
,Last
仅在 时生成check(Init) == true
。这可能会产生您想要的效果。
不过要小心。我++
在 LC 的左侧使用。您绝对应该对代码进行基准测试,看看这是否对性能有影响。
如果确实如此,并且仅当确实如此,您可能需要考虑使用以下内容:
variation3(1, L) ->
[ [Elem] || Elem <- L ];
variation3(N, L) ->
[ lists:reverse([Last|lists:reverse(Init)]) || Init <- variation2(N-1, L), check(Init), Last <- L].
也许值得,也许不……你需要对你的东西进行基准测试才能弄清楚。
推荐阅读
- python-3.x - 如何使用 discord.py 在欢迎消息中包含公会名称
- java - spark master 无法处理并发作业提交(AWS EMR)
- arrays - 紧急运行时错误索引超出范围 [3],长度为 3
- python - 查找熊猫数据框中两行字符串的差异
- hidden-markov-models - 了解如何计算马尔可夫链中的去除效果
- java - Android (Java) - 布局在边缘被切断
- java - Java 的实现细节在 JDK 中的什么位置?
- python - 按 Pandas 数据分组并保留值
- c++ - 函数标识符和变量标识符的关系?
- java - Java中欧几里得算法的最大公约数(GCD)