很抱歉,如果标题不好......
所以我的问题是我得到了这段代码:
asd (a:as) (b:bs)= tail(rox(tail(rox (tail (rox (a:as) (b:bs))) (b:bs))) (b:bs))
rox [] as = as
rox as [] = as
rox (a:as) (b:bs) = map abs (a-b:rox as bs)
我的类型必须是:asd :: [Int]->[Int]->[Int]
我花了半天时间找出一个好的解决方案,但我只能想到一个,所以如果有人能帮助我,我会很高兴。 我想从(a:as)列表中减去(b:bs)列表,之后我想删除第一个数字并再次使用结果(结果 - (b:bs)),直到我得到一个(长度(b:bs)) - 1)列表。如果(a:as)/结果低于(b:bs),则exapmle:00101< 10011我需要将所有(b:bs)数字更改为0(如果结果更高,则继续使用(b:BS))。使用上面的代码,exapmle工作正常,但我想在任何列表中使用它。也许我需要使用迭代函数,但我无法弄清楚如何。
以下是一个例子:
11010(a:as)
101(b:bs)
01110(result)
1110(after using tail)
101(b:bs again)
0100(result)
100(after tail)
101(b:bs)
001(result)
01(final result after using tail, so its 1number shorter than the (b:bs) list
非常感谢你的帮助!
编辑: 有了这个,我可以检查哪个二进制数更高,所以我可以将所有的bs数转换为0,但我不知道如何实现它。
(%>=%) :: [Int] -> [Int] -> Bool
(%>=%) [] [] = True
(%>=%) as [] = True
(%>=%) [] bs = False
(%>=%) as bs
| filter (/=0) (takeWhile (>(-1))(ro as bs))==[]=False
| elem 1 (takeWhile (>(-1))(ro as bs))==True=True
ro :: [Int] -> [Int] -> [Int]
ro [] bs = bs
ro as [] = as
ro (a:as) (b:bs) = (2*a) - b: ro as bs
结果:
asd [1,1,1,0,0,1,0,1,0,0,0,0] [1,1,0,1,1]
asd [0,1,1,1,1,0,1,0,0,0,0] [1,1,0,1,1]
asd [1,1,1,1,0,1,0,0,0,0] [1,1,0,1,1]
asd [0,1,0,1,1,0,0,0,0] [1,1,0,1,1]
asd [1,0,1,1,0,0,0,0] [1,1,0,1,1]
asd [0,1,1,0,0,0,0] [1,1,0,1,1] < here is something wrong because its: 1,1,0,1,0,0,0 and from here everything is wrong
asd [1,1,0,0,0,0] [1,1,0,1,1]
asd [1,0,0,0,0] [1,1,0,1,1]
asd [0,0,0,0] [1,1,0,1,1]
[0,0,0,0]
答案 0 :(得分:2)
您似乎正在尝试实现余数rem
(类似于模mod
)函数,但用于二进制列表。如果您将列表转换为Integer
并对其执行rem
,速度会快得多。
首先,一个从二进制转换为Integer
的函数:
unbinary :: [Int] -> Integer
unbinary = foldl (\ a b -> a * 2 + fromIntegral b) 0
然后,将Integer
转换为二进制的函数:
binary :: Integer -> [Int]
binary = reverse . go
where
go 0 = []
go d =
let (q, r) = quotRem d 2
in fromIntegral r : binary q
最后,为二进制列表处理rem
的函数:
remBinary :: [Int] -> [Int] -> [Int]
remBinary a b = binary $ inta `rem` intb
where
inta = unbinary a
intb = unbinary b
这个解决方案的“美感”是你可以用任何数字(3,6,13等)代替2,它可以用于任何基础 - 而不仅仅是二进制。
回答你原来的问题:
这确实是一个非常奇怪的功能,我会不使用iterate
。
asd :: [Int] -> [Int] -> [Int]
-- If there is nothing to subtract, let's assume that we should return as
asd as [] = as
asd as bs
-- If the length of `as` is shorter than `bs`, we are done.
| length as < length bs
= as
| head as == 0
= asd (tail as) bs
-- Otherwise, compute `rox as bs`, take its `tail`, and call `asd` recursively
| otherwise
= asd (tail (rox as bs)) bs
-- I simplified your version of this function a bit
rox :: [Int] -> [Int] -> [Int]
rox [] bs = bs
rox as [] = as
rox (a : as) (b : bs) = abs (a - b) : rox as bs
asd
的最后一部分也可以这样写:
= let diff = rox as bs
tailOfDiff = tail diff
in asd tailOfDiff bs
这样,它会更贴切地跟随您的描述。