我怎样才能创建一个函数来懒惰地为字符'_'和'*'进行排列,如下所示:
例如:
Main> function 3
["___","*__","_*_","__*","**_","_**","*_*","***"]
第一个元素仅由 组成_
,接下来的 3 个是列出的排列:*__
,第二个 3 是列出的排列,**_
最后一个元素仅包含*
。
我怎样才能做到这一点?
我怎样才能创建一个函数来懒惰地为字符'_'和'*'进行排列,如下所示:
例如:
Main> function 3
["___","*__","_*_","__*","**_","_**","*_*","***"]
第一个元素仅由 组成_
,接下来的 3 个是列出的排列:*__
,第二个 3 是列出的排列,**_
最后一个元素仅包含*
。
我怎样才能做到这一点?
这是另一个“正确顺序”版本:
function :: Int -> [String]
function c = concatMap helper $ zip (reverse [0..c]) [0..c]
helper :: (Int, Int) -> [String]
helper (c, 0) = [replicate c '_']
helper (0, c) = [replicate c '*']
helper (cUnderscores, cAsterisks) = map ('_' :) (helper (cUnderscores - 1, cAsterisks))
++ map ('*' :) (helper (cUnderscores, cAsterisks - 1))
你可能想看看replicateM
.
let k = ["_", "*"]
let p = [ a ++ b ++ c | a <- k, b <- k, c <- k ]
“正确顺序”版本:
import Data.List
function k = concatMap (nub . permutations . pat) [0..k]
where pat x = replicate x '*' ++ replicate (k-x) '_'
不过,我不知道如何在恒定时间内从一种排列过渡到另一种排列。