2016-05-15 93 views
1

這可能是一個愚蠢的問題,但我一直堅持這個問題現在幾個小時..我做了一個遺傳算法,但認爲我可以嘗試改善它一點。我想創建一個適應函數來比較兩個數字列表並返回一個值。如果兩個列表中包含的數字相同並且位於相同的「地點」,則該函數應返回+ 2.如果列表包含的數字相同但位置不正確,則應返回+1。比較兩個列表之間的元素 - Haskell

我已經完成了兩個不同的功能,這兩個功能都可以完成這些任務之一,但我無法設法將它們合併到一個功能中。這裏是功能:

samePlace _ [] = 0 
samePlace [] _ = 0 
samePlace (x:xs) (y:ys) 
    | x == y = (sP xs ys) + 2 
    | otherwise = sP xs (ys) 

此函數返回+2爲每個數字是相同的,是在正確的地方。

notSamePlace [] _ = 0 
notSamePlace _ [] = 0 
notSamePlace (x:xs) (ys) 
    | elem x (ys) = (notSamePlace xs ys) + 1 
    | otherwise = (notSamePlace xs ys) 

該函數返回+ 1是第二個列表中存在的第一個列表中的一個數字。

我得到的問題是,相同的地方功能需要拆分兩個列表,並通過他們一次一位數來比較它們,而不是同一地方的功能需要保持第二個列表完好無損地將其分開在頭部和尾部。如果有人能夠指引我如何解決這個問題,我會非常感激。

此外,我認爲這個功能可以提高在遺傳算法中找到解決方案所需的時間。如果我的解決方案是找到字符串「hello world」,我的想法是,具有基因「leolh owdrl」的個體應該比看起來像「hFz%l r0M/z」的基因更適合。在我的程序到目前爲止,第一個基因的適應值爲1(因爲'空間'是與目標字符相同位置的唯一字符),但第二個基因具有'h'和'空間'它會被賦予2的適應值。這是一個好的想法嗎?

謝謝!

+0

提示:寫函數,它接受兩個列表'(如,BS)'和返回'(C,如,BS')'其中'c'是在相同位置處於相同位置的字母的數量,'as''和'bs''是'as'和'bs',並刪除了這些常見字母。 – ErikR

+0

如果您需要編輯距離作爲您的健身功能:請參閱https://hackage.haskell.org/package/align包(披露:我是作者)。 – ron

+0

你能看出爲什麼'notSamePlace'函數對於長字符串來說會很慢嗎?你能想出一種方法來使用輔助數據結構來幫助嗎?提示:你可以在['containers'](https://hackage.haskell.org/package/containers)包中找到兩個明智的選項。其中之一更明顯適用;另一個實際上更快。 「 – dfeuer

回答

1

下面的函數使用zip來索引每個字符,它允許將完整的第二個列表傳遞給遞歸調用。

places :: String -> String -> Int 
places _ [] = 0 
places [] _ = 0 
places xs ys = zippedPlaces (zip xs [1..length xs]) (zip ys [1..length ys]) 

zippedPlaces :: [(Char, Int)] -> [(Char, Int)] -> Int 
zippedPlaces [] _ = 0 
zippedPlaces (x:xs) ys = 
    let match = filter (\(num, i) -> fst x == num) ys 
    in case match of 
     [] -> zippedPlaces xs ys 
     (a:_) -> (if snd a == snd x then 2 else 1) + zippedPlaces xs ys 
+0

謝謝Kapol的回答!甚至沒有考慮過你可以使用zip函數...有時你只需要一個新的視角來解決這個問題。再次感謝! :) –

+0

''*主數據。地圖數據。列表>地點「你好」「Hel」''' 看起來不聰明 – Lol4t0

0

假定沒有列表包含重複:

place [] _ = 0 
place _ [] = 0 
place (x:xs) (y:ys) = place xs ys + 
    if x == y then 1 else (if elem x ys then 2 else 0) + (if elem y xs then 2 else 0)