我在 Haskell 做一个任务。任务是在给定单词匹配、未命中和间隙插入分数的情况下给出两个字符串的最佳对齐方式。到目前为止,这是我们的代码。第一步是使用蛮力使其工作,稍后我们将使用记忆化来实现。但是,我们被困在当前位置。
我们的 optAlignment 函数无法正常工作。对于示例输入“writers”“vintner”,返回的最佳对齐应该是:
[("writ-ers","vintner-"), ("wri-t-ers","-vintner-"), ("wri-t-ers","v-intner-")]
但我们得到
[("writers","vintner"),("writ-ers","vintner-"),("writ-ers","v-intner"),("wri-ters","v-intner"),("wri-t-ers","v-intner-"),("writ-ers","-vintner"),("wri-ters","-vintner"),("wri-t-ers","-vintner-")]
所以正确的替代方案是存在的,但也有更多。我们制作了一个函数 totalScore,它表明我们得到的一些备选方案不是最优的(显然)。但是我们现在已经花了 2 个小时试图弄清楚,但没有取得任何进展。该代码还需要几分钟才能运行,这使得错误检查有点困难。
所以我们真的需要一些帮助来找出我们代码中的哪些部分是错误的。
-- String Alignment assignment
scoreMatch = 0
scoreMismatch = -1
scoreSpace = -1
type AlignmentType = (String,String)
optAlignments :: String -> String -> [AlignmentType]
optAlignments [][] = [("","")]
optAlignments (x:xs) [] = attachHeads x '-' (optAlignments xs "")
optAlignments [] (y:ys) = attachHeads '-' y (optAlignments "" ys)
optAlignments (x:xs) (y:ys) = maximaBy (uncurry similarityScore) $match++xSpacematch++ySpacematch
where match = attachHeads x y $optAlignments xs ys
xSpacematch = attachHeads x '-' $optAlignments xs (y:ys)
ySpacematch = attachHeads '-' y $optAlignments (x:xs) ys
similarityScore :: String -> String -> Int
similarityScore [][] = 0
similarityScore xs [] = scoreSpace * length xs
similarityScore [] ys = scoreSpace * length ys
similarityScore (x:xs) (y:ys) = max match $max xSpacematch ySpacematch
where match = similarityScore xs ys + score x y
xSpacematch = similarityScore xs (y:ys) + score x '-'
ySpacematch = similarityScore (x:xs) ys + score '-' y
score :: Char -> Char -> Int
score x '-' = scoreSpace
score '-' y = scoreSpace
score x y
| x == y = scoreMatch
| otherwise = scoreMismatch
-- attachHeads functions attaches the two arguments to the front of each list in the tuple
attachHeads :: a -> a -> [([a],[a])] -> [([a],[a])]
attachHeads h1 h2 aList = [(h1:xs,h2:ys) | (xs,ys) <- aList]
maximaBy :: Ord b => (a -> b) -> [a] -> [a]
maximaBy valueFcn xs = [a| a <- xs, valueFcn a == maxVal ]
where maxVal = maximum $map valueFcn xs
totalScore x y = sum $map (uncurry score) (zip x y)
--map (uncurry totalScore)
--outputOptAlignments string1 string2