2010-10-31 150 views
0
t = True 
f = False 
anzNachbarn :: [[Bool]] -> (Integer,Integer) -> Integer 
anzNachbarn a (x,y) 
     | x < 0 || y < 0=-1 
     | otherwise ... here comes the comparison 

這是一個例子基質:bool值在矩陣比較

[[True,False,False], 
[True,False,False], 
[False,True,False]] 

在這裏,我需要一個算法,它計算(對於給定的x和矩陣y位置)及其鄰國(只有「真」鄰居),併爲每個真正的鄰居增加1。

例如:anzNachbarn [[真,FALSE,FALSE],[真,FALSE,FALSE],[假,真,假]](0,1)

返回2背面。

:編輯

我仍然有一個問題,我怎麼能現在執行的結果矩陣的每個組成部分,具有真周邊領域命名元素的數字表示參數矩陣的相應單元適用於

[[真,FALSE,FALSE],

[真,FALSE,FALSE],

[假,真,假]]

函數func返回結果矩陣[[1,2,0],[2,3,1],[2,1,1]] with signature func :: [[Bool]] - > [[整數]] 你有什麼想法嗎?

回答

1

這是醜陋的,但似乎工作...

anzNachbarn :: [[Bool]] -> (Int,Int) → Integer 
anzNachbarn a (x,y) 
    | x < 0 || y < 0 = -1 
    | otherwise = sum [v x' y' | x' <- [max 0 (x-1)..x+1], 
           y' <- [max 0 (y-1)..y+1], 
           x ≠ x' || y ≠ y' ] 
    where v i j = if j >= length a 
         || i >= length (a !! 0) 
         || not (a !! j !! i) 
        then 0 else 1 

[編輯]

爲了整個數組轉換,你可以寫同樣醜陋

conv a = [line y | y <- [0 .. (length a) - 1]] 
    where line y = [anzNachbarn a (x,y) | x <- [0 .. ((length (a !! 0) - 1)]] 

請注意,這是可怕的表現。

+0

我怎樣才能改變索引(整數,整數)爲(整數,整數)程序運行正確 – marco 2010-11-01 06:13:45

+0

我仍然有一個問題,我現在怎麼能實現結果矩陣的每個組件,用True相鄰字段命名的數字表示參數矩陣的相應分量適用於[[True,False,False],[True,False,False],[False,True,False]],函數 轉換結果矩陣[[1,2,0], [2,3,1],[2,1,1]]帶簽名func :: [[Bool]] - > [[Integer]] – marco 2010-11-01 07:08:16

+0

Integer的問題是,那!期望一個Int。所以如果你寫'a! (來自整合j)! (來自I積分)'我認爲它應該與Integer一起工作。 – Landei 2010-11-01 08:05:12

3

在這種情況下,您幾乎可以肯定地想要使用一個數組(從Data.Array),因爲通過其索引在列表中查找項目非常緩慢。

這裏有一個快速的實現使用Array

countNeighbors :: Array (Int, Int) Bool -> (Int, Int) -> Int 
countNeighbors board (x, y) = length 
    [ (x', y') 
    | x' <- [x - 1, x, x + 1] 
    , y' <- [y - 1, y, y + 1] 
    , x' /= x || y' /= y 
    , inRange (bounds board) (x', y') 
    , board ! (x', y') 
    ] 

這是兩個發電機和三個後衛列表理解。發電機只是給我們提供了一個三乘三平方的九個位置的指數,集中在(x, y)(如果你不想讓拐角處的鄰居被考慮,你需要做一些小的改動)。 (x' /= y')忽略(x, y)本身。第二個拋出不在數組邊界內的位置。最後一名後衛拋出陣列中的位置,但具有False的值。

因此,我們現在有一個True值的鄰居索引列表。該列表的長度是所需的計數。

+0

謝謝你的幫助,但我需要它沒有陣列 – marco 2010-10-31 16:53:17

+0

護衛'x'/ = y''去除沿對角線的所有值,而不是忽略給定的值。我認爲你的意思是'x'/ = x || y'/ = y'。 – Paul 2010-11-02 05:30:28

+0

@保羅:你當然是對的。我輸入的太快了,但現在已經修復了。 – 2010-11-02 07:08:08