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

时间:2015-12-11 15:46:33

标签: string algorithm haskell combinations

如果给我一个像skhfbvqa这样的字符串,我将如何生成 next 字符串?对于此示例,它将是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

(请原谅我令人难以置信的糟糕的Haskell-ing :)还是一个菜鸟

所以我的问题是,我怎么能这样做?如果有多种方法,我们非常感谢它们之间的比较。谢谢!

3 个答案:

答案 0 :(得分:3)

这是一个带有基本转换的版本(这样你可以随意添加和减去):

encode x base = encode' x [] where
  encode' x' z | x' == 0 = z
               | otherwise = encode' (div x' base) ((mod x' base):z)

decode num base =
  fst $ foldr (\a (b,i) -> (b + a * base^i,i + 1)) (0,0) num

输出:

*Main> map (\x -> toEnum (x + 97)::Char) 
       $ encode (decode (map (\x -> fromEnum x - 97) "skhfbvqa") 26 + 1) 26

"skhfbvqb"

答案 1 :(得分:1)

我会去做一个帮助函数f :: Integer -> String和一个g :: String -> Integer,其中f 1 = "a",... f 27 = "aa"f 28 = "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

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

答案 2 :(得分:1)

我发现这个有效。它只是使用模式匹配来查看字符串是否以 z 开头,并相应地添加了一个 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