Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 在Haskell中生成下一个词典编纂字符串_String_Algorithm_Haskell_Combinations - Fatal编程技术网

String 在Haskell中生成下一个词典编纂字符串

String 在Haskell中生成下一个词典编纂字符串,string,algorithm,haskell,combinations,String,Algorithm,Haskell,Combinations,如果给我一个类似skhfbvqa的字符串,我将如何生成下一个字符串?对于本例,它将是skhfbvqb,下一个字符串将是skhfbvqc,依此类推。给定的字符串(和答案)将始终为N个字符长(在本例中,N=8) 我的尝试: 我试图生成可能组合的整个(无限)列表,并获得给定字符串的所需(下一个)字符串,但毫不奇怪,它太慢了,以至于我甚至没有得到N=6的答案 我使用了列表理解: allStrings = [ c : s | s <- "" : allStrings, c <- ['a'..'

如果给我一个类似
skhfbvqa
的字符串,我将如何生成下一个字符串?对于本例,它将是
skhfbvqb
,下一个字符串将是
skhfbvqc
,依此类推。给定的字符串(和答案)将始终为N个字符长(在本例中,N=8)

我的尝试:

我试图生成可能组合的整个(无限)列表,并获得给定字符串的所需(下一个)字符串,但毫不奇怪,它太慢了,以至于我甚至没有得到N=6的答案

我使用了列表理解:

allStrings = [ c : s | s <- "" : allStrings, c <- ['a'..'z'] ]

main = do
    input <- readFile "k.in"
    putStrLn . head . tail . dropWhile (not . (==) input) . map reverse $ allStrings

allStrings=[c:s | s我会去做一个helper函数
f::Integer->String
和一个
g::String->Integer
,其中
f1=“a”
,…
f27=“aa”
f28=“ab”
等等,以及与之相反的
g

然后
incrementString=f.succ.g

注:为了学习,我省略了
f
的实现

更新 对于另一种方法,您可以使用进位函数
inc':Char->(Char,Bool)
定义一个增量,然后

incString :: String -> String
incString = reverse . incString'
   where incString' [] = []
         incString' (x:xs) = case inc' x of (x',True) -> x': incString' xs
                                            (x',False) -> x':xs

注意:此函数不是尾部递归的!

我发现它可以工作。它只是使用模式匹配来查看字符串是否以az开头,并相应地添加一个额外的a

incrementString' :: String -> String
incrementString' []          = ['a']
incrementString' ('z':xs)    = 'a' : incrementString' xs
incrementString' (x:xs)      = succ x : xs

incrementString :: String -> String
incrementString = reverse . incrementString' . reverse

这是一个具有基本转换的版本(如果您愿意,您可以通过这种方式任意加减):

encode x base=encode'x[]其中
编码'x'z | x'==0=z
|否则=编码'(div x'基)((mod x'基):z)
解码数字基=
fst$foldr(\a(b,i)->(b+a*base^i,i+1))(0,0)个
输出:

*Main>map(\x->toEnum(x+97)::Char)
$encode(解码(映射(\x->fromEnum x-97)“skhfbvqa”)26+1)26
“skhfbvqb”

谢谢你的回复。我没有这样想;我会尝试一下!但是我想知道是否可以用更“Haskell-y”的方式(比如内置函数、单子等等)扫描
所有字符串
看起来效率非常低——类似于通过
\x->head.tail$dropWhile(/=x)[0..]
。它可以工作,但需要指数时间/空间。相反,我将字符串表示为一个向后列表,并对每个字符/数字执行标准的“带进位的加法”。正如预期的那样,这将具有线性最坏情况复杂度。(此外,由于几何和收敛,它也是一个摊销常数时间,因此是一种最优的)@chi Yep,
allStrings
效率极低。这只是我想到的第一件事。你的建议听起来很有趣。你能不能提供一个答案,但再加上几点提示/步骤?谢谢你的回答!这就像把字符串当作基数-26,对吗?用字符
[a-z]
而不是数字。@Roshnal是的,完全正确-这就像将字符串视为一个基数为26的数字,用字符
[a-z]
而不是数字。@Roshnal对于具有
a
s(视为零)的字符串,可能需要一些填充作为前缀A是的,这是真的。有趣的方法,也会尝试:)这对我来说很好。检查
incrementString“zzzzzz”
是您真正想要的——我提到这一点是因为您写道答案的长度必须是8。@chi您是对的,这里有一个问题。它给出了9 a的输出…但我的意思是问题提供者(这是一个更大的练习问题的一部分)已经提到答案将是N位数。再次阅读我的问题,似乎我有点不清楚。对不起:/