比较两个列表之间的元素-Haskell



这可能是一个愚蠢的问题,但我已经为这个问题困扰了几个小时了。。我做了一个遗传算法,但我想我可以试着改进一下。我想做一个适应度函数,比较两个数字列表并返回一个值。如果两个列表都包含一个相同的数字,并且位于相同的"位置",则函数应返回+2。如果列表中包含相同但位置错误的数字,则应返回+1。

我制作了两个不同的功能,它们都能完成其中一项任务,但我无法将它们合并为一个功能。以下是功能:

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。如果第一个列表中的数字之一存在于第二个列表中。

我遇到的问题是,同一个位置函数需要将两个列表拆分,并一次遍历一个数字来进行比较,而不相同的位置函数需要保持第二个列表的完整性,而不将其拆分为首尾部分。如果有人能为我指出解决这个问题的正确方向,我将不胜感激。

此外,我认为这个函数可以缩短在遗传算法中找到解决方案所需的时间。如果我的解决方案是找到字符串"你好世界",我的想法是,具有基因"leolh-owdrl"的个体应该比看起来像"hFz%lr0M/z"的基因更适合。到目前为止,在我的程序中,第一个基因的适应度值为1(因为"空格"是与目标字符位于同一位置的唯一字符),但第二个基因的"h"one_answers"空格"正确,因此它的适应度为2。这是个好主意吗?

谢谢!

Below函数使用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

假设没有列表包含重复项:

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)

最新更新