2016-07-05 29 views
0

我很新的哈斯克爾。我想通過以下方式來重新排序列表:哈斯克爾 - 獲取列表的中間數字

[5,6,7,8,9] -> [7,5,9,6,8] 
[6,7,8,5,4,3] -> [8,5,6,3,7,4] 

它想獲取中間的數字或列表的數量,並把它們的起始位置。之後,它應該開始獲取列表中的兩個外部數字並將它們添加進來並按照它的方式進行。我有以下代碼來獲取中間數字並將它們放入列表的開頭,但無法弄清楚開始將外部號碼添加到新列表中。

代碼:

-- import Data.List 
-- import System.IO 

longitude xs = length xs 

middle xs = length xs `div` 2 

addOne xs = middle xs - 1 

oneMore xs = length xs - 1 

otherCase xs = oneMore xs `div` 2 

valuea xs = xs !! middle xs 

valueb xs = xs !! addOne xs 

valuec xs = xs !! otherCase xs 

modulus xs = longitude xs `mod` 2 

order xs = midNums xs 

takes xs = take (otherCase xs) xs 

oddOne xs = otherCase xs + 1 

takeX xs = drop (oddOne xs) xs 

value xs = takes xs ++ takeX xs 

reorder xs = drop (otherCase xs)(take (middle xs + 1) xs) 

valueOdd xs = reorder xs ++ takes xs ++ takeX xs 

paruno xs = drop (middle xs + 1) xs 

pairTwo xs = take (addOne xs) xs 

midPair xs = take (addOne xs)(drop (middle xs -1) xs) 

--Get the numbers 
midNums xs = if modulus xs == 0 then midPair xs ++ paruno xs ++ pairTwo xs 
else valueOdd xs 

先進的感謝,任何幫助是極大的讚賞。

編輯:

我希望它是這樣工作的:Demo

回答

1

試試這個:

f :: (Num a) => [a] -> [a] 
f [] = [] 
f [x] = [x] 
f xs = if len `mod` 2 == 1 then flatten [xs !! half] else flatten [xs !! (half-1), xs !! half] 
    where len = length xs 
      half = len `div` 2 
      firsthalf = take (half-1) xs 
      secondhalf = (reverse . take half . drop (half+1)) xs 
      outtoin = zipWith (\x y -> x:y:[]) firsthalf secondhalf 
      flatten = concat . flip (:) outtoin 

其分解:

  • 首先得到該中點(S)
  • 接下來得到列表的兩半瀘定中間分子
  • 從外向內使用Zip
  • 拼接拉鍊結果趨於平緩,並添加到中間的元素列表

Demo

+0

由於它的工作原理建立的名單,但是它不工作我希望它的工作方式。我想在兩個中間數字後面列表的外部數字,並開始工作。像這樣[Demo](http://rextester.com/EBSFBF27492) –

+0

我已經更新了代碼。在'secondhalf'函數中我的索引有點偏離。你可能想再試一次 –