2013-03-17 98 views
1

我試圖交換haskell中列表的第一個和最後一個元素。我試過模式matchnig,表達式,函數等,這是我的最後一次嘗試:交換第一個和最後一個元素haskell

cambio xs = [ cabeza++([x]++cola)|x<-xs, cabeza <- init x, cola <- last x, drop 1 x, drop 0 ([init x])]

我的編譯器會引發下一個錯誤:

Couldn't match expected type `Bool' with actual type `[a0]' 
    In the return type of a call of `drop' 
    In the expression: drop 1 x 
    In a stmt of a list comprehension: drop 1 x 

誰能幫助我?我試着2天

+0

我需要做我自己的實現,「反向」顛倒完整列表不僅僅是第一個和最後一個 – user2180528 2013-03-17 23:32:36

+0

是的,倒過來不僅僅是交換第一個和最後一個元素,但由於沒有指定清單的其餘部分必須停留在原來的位置,這就是解決方案。你不能認爲反向不會交換列表的第一個和最後一個元素,對嗎? – Ingo 2013-03-17 23:36:44

+0

'swap(x:xs)= concat [[last xs],init xs,[x]]'類似的東西? – DarthFennec 2013-03-17 23:40:21

回答

2

我認爲,名單是不是這樣做的最好的數據結構,但在這裏它去做到這一點:

swap list = last list : (init . tail $ list) ++ [head list] 

這將需要遍歷列表在長名單上會變慢。這是鏈接列表的性質。


更新與問題提問者基地的情況:

swap [] = [] 
swap [a] = [a] 
swap list = last list : (init . tail $ list) ++ [head list] 
+0

[]和[1]失敗。如果您必須提供完整的解決方案,請確保它們是正確的。 – Ingo 2013-03-17 23:47:00

+1

我解決了添加一些基本案例的問題。下面是解決方案:swap [a] = [a] swap [] = [] 交換列表=最後列表:(init。tail $ list)++ [head list] – user2180528 2013-03-18 00:33:01

4

下面是一些提示:

  1. 你不能用列表解析解決這個問題。
  2. 確定基礎(不重要)的情況 - 空白列表和一個元素的列表。寫出涵蓋這些情況的方程式。
  3. 在所有其他情況下,輸入列表的長度將是> = 2。你想要的列表是

    [Z] ++ ++ XS [α]

其中z是最後一個元素是輸入列表的第一個元素,xs是輸入的中間部分。

現在告訴我(或者你自己),如果輸入字符串的長度是k,xs將會持續多長時間?

  1. 寫出涵蓋大於1個元素的列表情況的等式。你可以使用頭像,最後一個,長度,下降或拿等功能。
+0

im發佈我自己的嘗試證明即時消息不要求複製,粘貼的東西。即使有人給我正確的解決方案,我不明白這是什麼問題,如果它很好地解釋 – user2180528 2013-03-17 23:58:56

+0

爲什麼這個不能用列表理解解決?我強硬他們像功能,但具有不同的形式 – user2180528 2013-03-18 00:01:26

+0

@ user2180528列表理解不改變元素的順序,但在列表中的元素上運行。 – Jonke 2013-03-18 08:43:33

2

這是做一個非常簡單的事情,特別是與標準列表功能:

swapfl [] = [] 
swapfl [x] = [x] 
swapfl (x:xs) = (last xs : init xs) ++ [x] 

或者沒有他們(雖然這是不易閱讀,通常不這樣做,不推薦):

swapfl' [] = [] 
swapfl' [x] = [x] 
swapfl' (x:xs) = let (f, g) = sw x xs in f:g 
    where sw k [y] = (y, [k]) 
     sw k (y:ys) = let (n, m) = sw k ys in (n, y:m) 

或許多其他方式之一。

我希望有幫助......我知道我沒有做太多的解釋,但坦白地說,很難準確地說出你對這個功能有什麼困難,看起來你也好像完全一樣誤解列表理解。如果我解釋這些,我認爲這可能是最有益的。

And why this cant be solved with a list comprehension? I tough they were like functions but with a different form

不是。列表推導對於輕鬆定義列表非常有用,並且它們與數學中的建立者符號密切相關。這對於這個特定的應用程序來說沒有用處,因爲雖然他們擅長修改列表的元素,但是理解並不擅長重新排序列表。

在理解,你有三個部分:在列表中的一個元素的定義,一個或多個輸入列表,以及零個或多個謂詞:

[ definition | x <- input1, y <- input2, predicate1, predicate2 ] 

的定義描述列表中的單個元素我們正在根據變量輸入中的箭頭指向(在這種情況下是x和y)。每個輸入都有一個箭頭右側的列表和一個左側的變量。通過將輸入列表中的每個元素組合提取到這些變量中,並使用這些值評估定義部分,從而構建列表中的每個元素。例如:

[ x + y | x <- [1, 3], y <- [2, 4] ] 

這產生:

[1 + 2, 1 + 4, 3 + 2, 3 + 4] == [3, 5, 5, 7] 

此外,還可以包括謂詞,這就像過濾器。每個謂詞都是一個按照輸入元素定義的布爾表達式,每當有新的列表元素時,每個謂詞都被評估。如果任何謂詞出現錯誤,那些元素就不會放入我們正在製作的列表中。

讓我們看看你的代碼:

cambio xs = [ cabeza++([x]++cola) | x<-xs, cabeza <- init x, cola <- last x, 
            drop 1 x, drop 0 ([init x])] 

這個理解的輸入是x <- xscabeza <- init xcola <- last x。第一個意思是xs中的每個元素將用於定義新列表的元素,並且每個元素將被命名爲x。其他兩個沒有任何意義,因爲initlast[a] -> a類型,但位於箭頭的右側,因此必須是列表,並且x必須是列表的元素,因爲它位於其左側箭頭,所以爲了這個甚至編譯,xs必須是[[[a]]],我敢肯定這不是你想要的。

您使用的謂詞是drop 1 xdrop 0 [init x]。我有點理解你想要做的第一個,刪除列表中的第一個元素,但這不會工作,因爲x只是列表中的一個元素,而不是列表本身。在第二個,drop 0的意思是「從下面的列表開始刪除零元素」,這絕對不會做任何事情。無論哪種情況,在謂詞中加入類似的東西都是行不通的,因爲謂詞需要是一個布爾值,這就是爲什麼你得到編譯器錯誤。下面是一個示例:

pos xs = [ x | x <- xs, x >= 0 ] 

此函數接受一個數字列表,刪除所有負數並返回結果。謂詞是x >= 0,它是一個布爾表達式。如果表達式的計算結果爲false,則評估的元素將從結果列表中過濾出來。

您使用的元素定義是cabeza ++ [x] ++ cola。這意味着「結果列表中的每個元素本身就是一個列表,它由列表cabeza中的所有元素組成,後面跟着一個包含x的元素,後面跟着列表cola中的所有元素」,這看起來與所有元素相反你是爲了。請記住,管道字符之前的部分定義了單個元素,而不是列表本身。另外請注意,在變量周圍放置方括號會創建一個包含該變量的新列表,並且僅包含該變量。如果你說y = [x],這意味着y包含一個單獨的元素x,並且不會說x是否是一個列表。

我希望能幫助清理一些事情。

+0

這是一個非常全面的答案,很好的工作 – 2013-03-18 14:00:00

相關問題