如果给我一个像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 :)还是一个菜鸟
所以我的问题是,我怎么能这样做?如果有多种方法,我们非常感谢它们之间的比较。谢谢!
答案 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