我正在尝试编写一个函数,该函数找到具有k
位数的给定z
数字的n
个连续数字的最高乘积。
例如:
z = 1240313 -- number entered
n = 7 -- number of digits
k = 2 => 2*4 => 8 -- example if k = 2
k = 3 => 3*1*3 => 9
k = 4 => 0
如果k > n
我被要求收回错误。
直到现在我的想法是从给定的数字z
逐个获取所有数字并将它们插入列表中。然后我可能会使用这个列表,但我不确切知道如何。
我设法处理错误(我认为) 这是我的代码,直到现在:
myList 0 = []
myList x = (x `mod` 10 : myList (x `div` 10))
myReverse x = reverse (myList x)
maxConProduct :: Integer -> Integer -> Integer
maxConProduct z k | k > length(myReverse) = error "more consecutive digits entered as required"
我是Haskell和编程世界的新手。我很感激能帮到这个问题。
答案 0 :(得分:2)
maximum . map product . takeWhile ((==n).length) . map (take n) . tails
你可以通过编写功能来非常干净地完成这项工作:
import Data.List (tails)
import Data.Char (isDigit)
maxProd :: (Num a, Ord a) => Int -> [a] -> a
maxProd n = maximum -- biggest
. map product -- product in the list
. takeWhile ((== n) . length) -- once the too-short ones have gone
. map (take n) -- when you take the first n of each
. tails -- of the tails of the original
请注意
((== n) . length) :: [a] -> Bool
首先找到列表的长度,如果该长度与True
匹配,则给出n
。
通过举例说明,让我们通过您的示例跟踪。注意尾部是如何具有所有长度的,但是当我们map (take 3)
时它只保留每个尾部的前三个。另请注意,有三个列表太短([1,3],[3],[]
),这就是我们takeWhile ((==3).length)
的原因。
ghci> tails $ [1,2,4,0,3,1,3]
[[1,2,4,0,3,1,3],[2,4,0,3,1,3],[4,0,3,1,3],[0,3,1,3],[3,1,3],[1,3],[3],[]]
ghci> map (take 3) . tails $ [1,2,4,0,3,1,3]
[[1,2,4],[2,4,0],[4,0,3],[0,3,1],[3,1,3],[1,3],[3],[]]
ghci> takeWhile ((==3).length) . map (take 3) . tails $ [1,2,4,0,3,1,3]
[[1,2,4],[2,4,0],[4,0,3],[0,3,1],[3,1,3]]
ghci> map product . takeWhile ((==3).length) . map (take 3) . tails $ [1,2,4,0,3,1,3]
[8,0,0,0,9]
ghci> maximum . map product . takeWhile ((==3).length) . map (take 3) . tails $ [1,2,4,0,3,1,3]
9
现在,当n
超过原始列表的长度时会出现错误,因为takeWhile
将过滤掉所有列表,并且您将获取最大的空列表,但是更明确的信息会更有帮助。从单个Int转换它也很方便:
digits :: Int -> [Int]
digits = map (read . (:"")) . show
通过将显示的String的每个字符转换为String本身,方法是将它放在带有(:“”)的空字符串前面,然后读取每个字符。最初我是从字符串中取出来的,因为我错误地认为这就是你所拥有的。没关系。
findMaxProd :: Int -> Int -> Int
findMaxProd n i
| n > length (show i) = error "findMaxProd: product length exceeds number length"
| otherwise = maxProd n . digits $ i
在行动中,这给出了:
ghci> findMaxProd 10 1240313
*** Exception: findMaxProd: product length exceeds number length
ghci> findMaxProd 3 1240313
9
答案 1 :(得分:1)
另一种解决方案是这样的:
maxConProduct z k | k > length (myReverse z) = error "more consecutive digits entered as required"
maxConProduct z k = solve (myReverse z) [] k
where solve :: (Num a, Ord a) => [a] -> [a] -> Int -> a
solve [] acc _ = head $ reverse $ sort acc
solve x'@(x:xs) acc k = if k > length x'
then solve [] acc k
else solve xs (product (take k x'):acc) k
ghci中的演示:
λ> maxConProduct 1240313 2
8
λ> maxConProduct 1240313 3
9
λ> maxConProduct 1240313 4
0
λ> maxConProduct 1240313 8
*** Exception: more consecutive digits entered as required
您可以在solve
函数中看到,我正在获取所有首个k
个数字的产品,并将其累积在列表acc
中。一旦输入列表为空,那么我只需对acc
进行排序并给出其中的最高元素。
答案 2 :(得分:0)
试试这个:
maxProduct number k
| length (show number) < k = error "more consecutive digits entered as required"
| otherwise = maxProductHelp (transform number) k
where
transform 0 = []
transform number = mod number 10 : transform (div number 10) -- returns digits
maxProductHelp digits k = maximum $ products digits k -- gets maximum
where
products d k -- returns a list of products of consecutive groups of length k
| length d < k = []
| otherwise = (product $ take k d) : products (tail d) k
您的maxConProduct
已实施为maximum $ products digits k
让我们看看这个解决方案:
maxProduct
调用maxProductHelp
,号码以某种方式更改。transform
只返回指定号码的数字。maxProductHelp
现在获得了products
返回的列表的最大值。products
会返回长度为k
的连续子列表的产品列表。最重要的功能是products
,这个功能相对容易理解:
我们希望产品返回k
个连续数字的产品列表,因此我们只将k
个连续数字的乘积合并到下一个k
个连续数字的乘积中。如果我们的剩余数字列表比我们指定的k
短,那么我们返回一个空列表,其中包含所有内容。
这里只是products
的一个小例子:
products [3,1,3,0,4,2,1] 3 = (product [3,1,3]) : products [1,3,0,4,2,1]
products [1,3,0,2,4,2,1] 3 = (product [1,3,0]) : products [3,0,4,2,1]
products [3,0,4,2,1] 3 = (product [3,0,4]) : products [0,4,2,1]
products [0,4,2,1] 3 = (product [0,4,2]]) : products [4,2,1]
products [4,2,1] 3 = (product [4,2,1]]) : products [2,1]
products [2,1] = []
这只是一个清单:
9 : 0 : 0 : 0 : 8 : [] == [9,0,0,0,8]