我正在创建一个比较两个字符串的函数,以查看是否有一个是另一个字符串的重新排列。例如" hhe"和"嘿"会产生真实但是" hhe"和"嘻嘻"会是假的。我想我可以通过总结字符串的元素并查看它们是否相同来做到这一点。我知道haskell,所以我不知道我是否可以像C代码那样总结字符代码:
comp :: String -> String-> Bool
comp x y = (sum x) == (sum y)
编译时会产生错误。
答案 0 :(得分:8)
您可以先排序,然后比较字符串
import Data.List
import Data.Function
comp = (==) `on` sort
然后可以像这样使用
"abcd" `comp` "dcba" --yields True
答案 1 :(得分:2)
“求和”两个字符串是没有意义的。请改用permutations
:
comp :: String -> String -> Bool
comp x = (`elem` permutations x)
答案 2 :(得分:1)
虽然您的实施存在问题,但正如其他人所建议的那样,您问题的直接答案是您可以先使用Int
将字符转换为fromEnum
(支持算术的类型)。< / p>
> sum . map fromEnum $ "heh"
309
答案 3 :(得分:0)
将您的示例代码视为面值,问题是Char
未实现Num
,因此sum :: Num a => [a] -> a
不兼容。
但是,我们可以通过fromEnum
将Char
转换为Int
来解决这个问题:
isPermutationOf :: String -> String-> Bool
isPermutationOf x y = hash x == hash y
where hash = sum . map fromEnum
这将适用于您的示例案例:
λ isPermutationOf "hhe" "heh"
True
缺点是它也有一些误报:
λ isPermutationOf "AAA" "ab"
True
我们可以尝试通过确保输入的长度,最大值和分钟相同来减少这些:
isPermutationOf :: String -> String-> Bool
isPermutationOf x y = hash x == hash y && maximum x == maximum y && minimum x == minimum y
where hash = sum . map fromEnum
但是,虽然抓住了一些案例
λ isPermutationOf "AAA" "ab"
False
它并没有全部抓住它们
λ isPermutationOf "abyz" "acxz"
True
为此,我们确实需要确保两个输入中的每个Char
都有相同的数量。我们可以使用Data.Map.Map
来存储每个Char
的计数,或者使用Data.List.sort
对每个输入进行排序,但是如果我们只想使用{{1} },我们需要推出自己的解决方案。
有any number of examples on how to write quicksort
in haskell out there,所以我不会告诉你如何做到这一点。所以这是一个使用数学的笨Prelude
。
isPermutationOf
基本上,我们可以将isPermutationOf xs ys = all (\k -> powsum k as == powsum k bs) [0..n]
where as = map fromEnum xs
bs = map fromEnum ys
n = length xs
powsum k zs = sum (map (^k) zs)
- 长度字符串视为一组n
未知数。 n
检查isPermutationOf
等式:
n+1
本质上是长度检查。给定eq0
,其他xs
方程可以计算出n
未知数的n
方程,这将为n
唯一的排列提供解决方案。< / p>
但实际上,你应该使用(桶)排序,因为上面的算法是ys
,这种检查慢。
答案 4 :(得分:0)
如果你不想使用标准库(学习目的)功能,你可以快速排序两个字符串并检查字符串的相等性(奖励:quickSort)
isEqual :: String -> String -> Bool
isEqual a b = sortString a == sortString b
where
sortString :: String -> String
sortString [] = []
sortString (x:xs) = sortString (filter (<x) xs) ++ [x] ++ sortString (filter (>=x) xs)