【发布时间】:2020-03-21 09:22:47
【问题描述】:
不确定“动态”是否适合这个问题。
我一直在努力寻找压缩多个列表的解决方案
进入一个列表,但我开始认为我的方法是不可能的。
它适用于两个列表,但不适用于三个(可能不会超过三个)。
该函数应该作为transpose 工作,但会产生一个整数列表和
不是整数列表的列表。但如果它产生一个列表列表,它也会
工作。理论上,该函数应该适用于任意数量的列表。
例如 [1,2,3] myTranspose [4,5,6] myTranspose [7,8,9] 应该会导致 [1, 4, 7, 2, 5, 8, 3, 6, 9]
这可能吗?
到目前为止我的尝试:
myTranspose :: [Int] -> [Int] -> [Int]
myTranspose [] [] = []
myTranspose [x] [] = [x]
myTranspose [] [y] = [y]
myTranspose [x] [y] = [x,y]
myTranspose (x:xs) [y] = (x:y:xs)
myTranspose [x] (y:ys) = (x:y:ys)
myTranspose (x:xs) (y:ys) = [x,y] ++ zip' xs ys
编辑我的实际问题:
我应该从一开始就问这个,但我认为它会 将问题转换为整数列表更简单。对此感到抱歉。
我有一个数据类型 Function 和一个链接 Functions 的函数
一起:
data Function where
(|||) :: Function -> Function -> Function
A :: Char -> Function
B :: Int -> Function
chain :: Function -> Function -> Function
chain f1 f2 = f1 ||| f2
而且我还有一个功能应该像我上面描述的那样工作:
(<|||>) :: Funcion -> Function -> Function
...something like this..
(<|||>) (p1 ||| p2) (q1 ||| q2) = (p1 <|||> q1) ||| (p2 <|||> q2)
(<|||>) (p1 ||| p2) q = p1 <|||> p2 ||| q
(<|||>) p (q1 ||| q2) = p ||| q1 <|||> q2
(<|||>) p q = p ||| q
我设法用普通的列表和普通的 像moonGoose建议的转置功能。但问题是 如果我这样做,编译器会抱怨没有足够的内存 那样。 函数调用看起来像这样,除了列表是 非常大:
transpose ((A 'a' ||| B 5 ||| A 'n') <|||>
(A 'o' ||| B 3 ||| A 'p') <|||>
(A 'i' ||| B 0 ||| A 'l'))
但是当我使用“我的”列表功能和不完美的自定义运行程序时 transpose-function 编译器不会抱怨。我的想法是,这与懒惰有关。这可能是问题吗? 感谢您的帮助。
【问题讨论】:
-
我认为您必须为 2 对 3 输入列表编写不同的版本。这不是压缩,而是当您一次从每个列表中获取一个元素而不是从您正在获取的输入中交替时,这个名称甚至暗示了一个有用的实现技巧。
alt [] ys = ys; alt (x:xs) ys = x : alt ys xs并且很容易看到如何将其扩展到 3+ 输入列表。 -
concat . transpose有什么问题?提供您想要实现的目标的完整背景会很有帮助。 -
您的规范在数学上看起来是不可能的。它似乎要求
[1,2] t [3,4]为[1,3,2,4],以及[1,3,2,4] t [5,6]为[1,5,3,6,2,4],但您还希望([1,2] t [3,4]) t [5,6]为[1,3,5,2,4,6],与之前的结果相冲突。 -
我迷路了。您说“当我使用列表函数和不完美的自定义转置函数运行程序时,编译器不会抱怨”。这是否意味着你已经解决了你的问题?如果不是,为什么不呢?关于不同的代码库,您说“问题是编译器抱怨没有足够的内存”。我怎样才能自己重现这个观察结果?我投票结束,因为这对于您所面临的确切问题以及导致它的确切代码是多么模糊。
-
@datamoose 告诉我您遇到内存错误是无用,而无需说明重现内存错误的确切步骤。它可能是您的程序中的某些内容,或者您运行它的方式,或者如果我无法重现它的话。