帮助haskell旋转代码

ano*_*on1 2 haskell

好的,所以我知道这有点不对,但我错过了什么?代码是用以下单词旋转单个字母:

rotate 1   "hello" "ohell"  
rotate -1  "hello" "elloh"
Run Code Online (Sandbox Code Playgroud)

我的代码是:

module Main where

import System

main = do  
        (arg1:_) <- getArgs  
        xs <- getContents  
        putStr  (rotate xs arg1)  

rotate input w1 = unlines [ process line | line <- lines input ]  
        where process line = unwords [ word | word <- words line ]  
         map rotate n xs = drop n xs ++ take n xs  
Run Code Online (Sandbox Code Playgroud)

到目前为止,这是否正确,任何线索/提示下一步去哪里?

所以有点像这样:

shift :: a -> Int -> a
rotate :: a -> Int -> a

 x shift i   | i<0       = x shiftR (-i)
             | i>0       = x shiftL i
             | otherwise = x

 x rotate  i | i<0       = rotateR (-i)
             | i>0       = rotateL i
             | otherwise = x
Run Code Online (Sandbox Code Playgroud)

Ezr*_*zra 20

快速回答:

试试这个:

rotate :: Int -> [Char] -> [Char]
rotate x st = take (length st) $ drop (negate x `mod` length st) $ cycle st
Run Code Online (Sandbox Code Playgroud)

它产生:

rotate (1) "hello"
>>> "ohell"
rotate (-1) "hello"
>>> "elloh"
Run Code Online (Sandbox Code Playgroud)

说明:

这需要的洞察力是对cycle功能的了解,它永远重复一个字符串.

cycle "ezra"
>>> "ezraezraezraezraezr..." (forever)
Run Code Online (Sandbox Code Playgroud)

利用这些知识,我们可以利用length,takedrop为我们提供我们想要的字符串部分.我们也将使用negatemod数学部分.


长度

length 返回列表的长度(字符串是字符列表).

length "ezra"
>>> 4
Run Code Online (Sandbox Code Playgroud)

采取

take n返回n列表中的第一项.

take 9 (cycle "ezra")
>>> "ezraezrae"
Run Code Online (Sandbox Code Playgroud)

下降

drop n返回整个列表,第一个n元素除外.

drop 3 "ezra"
>>> "a"
drop 3 (take 9 (cycle "ezra"))
>>> "aezrae"
Run Code Online (Sandbox Code Playgroud)

MOD

使用该mod功能,我们可以获得适当的偏移.反引号`使函数"中缀",这使它更容易理解.如果您不熟悉模运算,那么这就是除法之后的"余数" .

10 `mod` 3
>>> 1
Run Code Online (Sandbox Code Playgroud)

这将给我们起点.


否定

negate n返回否定n,我们需要"反转"方向,并获得你想要的输出.

negate 10
>>> -10
Run Code Online (Sandbox Code Playgroud)

当我们把它们放在一起时,我们得到了上面的功能.当然,有很多方法可以做到这一点:这是一个.

在我上面的解决方案中,我按以下顺序开发了它.

  1. 获取无限列表:

    rotate x st = cycle st
    
    Run Code Online (Sandbox Code Playgroud)
  2. 选择正确数量的字符:

    rotate x st = take (length st) $ cycle st
    
    Run Code Online (Sandbox Code Playgroud)
  3. 从正确的位置取角色:

    rotate x st = take (length st) $ drop (x `mod` length st) $ cycle st
    
    Run Code Online (Sandbox Code Playgroud)

在这一点上,我有我想要的,但必须添加,negate以便我的输出匹配你的.

我还添加了类型签名.我喜欢尽可能多地明确我的功能.

  • 看起来这看起来像家庭作业我认为提供完整的答案有点多,但在长期解释上做得很好. (3认同)