我必须更改我的代码才能工作吗?
What do I have to change in my code to work?
我不知道我的代码有什么问题。我可以得到一些帮助来理解它吗?
Use longestChain to see how long the longest string in a text is made up of identical characters!
Examples:
longestChain "2111234" == 3
longestChain "0023212212222" == 4
longestChain "23232323232" == 1
longestChain "+++++!!!-------" == 7
longestChain :: String -> Int
longestChain (x:y:xs)
| x == y = 1 + longestChain xs
| otherwise = longestChain (y:xs)
这不是干净的,但它有效。
longestChain :: String -> Int
longestChain [] = 0
longestChain xs = go xs 0 1 where
go [] curr res = res
go [x] curr res
| curr > 0 = max (curr+1) res
| otherwise = res
go (x:y:xs) curr res
| x == y = go (y:xs) (curr+1) (max (curr+1) res)
| curr > 0 = go (y:xs) 0 (max (curr+1) res)
| otherwise = go (y:xs) 0 res
当我们找到相似的字符时,将函数的结果加一是不够的。我们需要计算字符串中的每个链和 return 我们找到的最长长度。这就是 curr
和 res
所关心的。
此外,当您找到 2 个字符匹配时,您需要将第二个添加到您的列表中以与下一个匹配,否则您会错过一个。另外,当你找到一个不匹配的时候,如果你的curr
大于0,说明这个字符属于上一个链的末尾,所以你加一个
> :m Data.List
Data.List> maximum $ map length $ group $ "+++++!!!-------"
7
group :: Eq a => [a] -> [[a]]
在 Data.List
.
“group 函数采用一个列表和 returns 一个列表列表,使得结果的串联等于参数。此外,结果中的每个子列表仅包含相等的元素。”
map length
returns 一个列表,每个子列表都替换为它的长度。
maximum
returns 这些长度的最大值。
我是怎么找到 group
的?我搜索了 Hoogle 具有该签名的函数。
更多的是@user1984 回答的风格。我仍然会说这段代码很难 read/is 混淆问题。
longestChain :: String -> Int
longestChain xs = go xs 0 where
go [] curr = curr
go [x] curr = curr+1
go (x:y:xs) curr | x == y = go (y:xs) (curr+1)
| otherwise = max (curr+1) (go (y:xs) 0)
(此处需要分支 go [] curr = ...
,因为 longestChain
可能已将空字符串传递给 go
。)
curr
总是计数 'in arrears',所以如果 go
在字符串末尾得到一个单例 [x]
,那一定是最后一个字符当前链,增加长度。
如果go
找到相邻的相同字符x == y
,为x
加1,在尾部递归。
如果go
找到相邻的不同字符otherwise
,仍然为x
加1(它是当前链的最后一个字符);开始新的尾巴计数。 Return 递增的max
curr
从尾部cp max
。
测试:
Main> longestChain ""
0
Main> longestChain "a"
1
Main> longestChain "Mississippi"
2
Main> longestChain "+++++!!!-------"
7
Main> longestChain "+++++!!!-------*"
7
我不知道我的代码有什么问题。我可以得到一些帮助来理解它吗?
Use longestChain to see how long the longest string in a text is made up of identical characters!
Examples:
longestChain "2111234" == 3
longestChain "0023212212222" == 4
longestChain "23232323232" == 1
longestChain "+++++!!!-------" == 7
longestChain :: String -> Int
longestChain (x:y:xs)
| x == y = 1 + longestChain xs
| otherwise = longestChain (y:xs)
这不是干净的,但它有效。
longestChain :: String -> Int
longestChain [] = 0
longestChain xs = go xs 0 1 where
go [] curr res = res
go [x] curr res
| curr > 0 = max (curr+1) res
| otherwise = res
go (x:y:xs) curr res
| x == y = go (y:xs) (curr+1) (max (curr+1) res)
| curr > 0 = go (y:xs) 0 (max (curr+1) res)
| otherwise = go (y:xs) 0 res
当我们找到相似的字符时,将函数的结果加一是不够的。我们需要计算字符串中的每个链和 return 我们找到的最长长度。这就是 curr
和 res
所关心的。
此外,当您找到 2 个字符匹配时,您需要将第二个添加到您的列表中以与下一个匹配,否则您会错过一个。另外,当你找到一个不匹配的时候,如果你的curr
大于0,说明这个字符属于上一个链的末尾,所以你加一个
> :m Data.List
Data.List> maximum $ map length $ group $ "+++++!!!-------"
7
group :: Eq a => [a] -> [[a]]
在 Data.List
.
“group 函数采用一个列表和 returns 一个列表列表,使得结果的串联等于参数。此外,结果中的每个子列表仅包含相等的元素。”
map length
returns 一个列表,每个子列表都替换为它的长度。
maximum
returns 这些长度的最大值。
我是怎么找到 group
的?我搜索了 Hoogle 具有该签名的函数。
更多的是@user1984 回答的风格。我仍然会说这段代码很难 read/is 混淆问题。
longestChain :: String -> Int
longestChain xs = go xs 0 where
go [] curr = curr
go [x] curr = curr+1
go (x:y:xs) curr | x == y = go (y:xs) (curr+1)
| otherwise = max (curr+1) (go (y:xs) 0)
(此处需要分支 go [] curr = ...
,因为 longestChain
可能已将空字符串传递给 go
。)
curr
总是计数 'in arrears',所以如果 go
在字符串末尾得到一个单例 [x]
,那一定是最后一个字符当前链,增加长度。
如果go
找到相邻的相同字符x == y
,为x
加1,在尾部递归。
如果go
找到相邻的不同字符otherwise
,仍然为x
加1(它是当前链的最后一个字符);开始新的尾巴计数。 Return 递增的max
curr
从尾部cp max
。
测试:
Main> longestChain ""
0
Main> longestChain "a"
1
Main> longestChain "Mississippi"
2
Main> longestChain "+++++!!!-------"
7
Main> longestChain "+++++!!!-------*"
7