haskell 如果特定值重复,则返回Bool

qij5mzcb  于 2023-02-04  发布在  其他
关注(0)|答案(3)|浏览(147)

我目前正在为学校做一个关于电子邮件识别的项目,但是代码的某个部分我已经被卡住了很长一段时间,我一直在试图弄清楚如果某个值重复,我如何返回Bool
这是我的当前代码:
其思想是构建一个函数来搜索某个值是否重复

repeated :: [Char] -> Bool
repeated [] = False
repeated [_] = False
repeated (x:xs) = if elem x xs then True else repeated xs

在代码的这一部分,我不知道如何指定如果Bool重复时要返回的值

special :: [String] -> [String]
special x = filter (elem ['.','_']) (map repeated x)

预期结果如下:特殊"穿孔.." True

zc0qhyus

zc0qhyus1#

现在您已经有了一个解决方案,所以我不觉得我破坏了一个很好的学习体验,这里有一些您可能会喜欢的其他实现想法。
如果要检查单个字符的重复状态,可以只要求该字符的副本,然后检查是否有两个(或更多)副本。

repeats :: Eq a => a -> [a] -> Bool
repeats a as = case filter (a==) as of
    _:_:_ -> True
    _ -> False

然而,如果你有很多repeats查询要做,这可能会降低效率。如果是这样,你可能需要对列表进行预处理,支付一些前期成本以使未来的查询更快。一种方法是对每个元素进行计数。

import qualified Data.Map as M

count :: Ord a => [a] -> M.Map a Int
count as = M.fromListWith (+) [(a, 1) | a <- as]

给定计数,很容易检查给定字符是否重复。

repeats' :: Ord a => a -> M.Map a Int -> Bool
repeats' a as = M.findWithDefault 0 a as >= 2

例如,要一次检查多个字符是否重复,可以编写:

multirepeats :: Ord a => [a] -> [a] -> Bool
multirepeats needle haystack = or [repeats' a as | a <- needle] where
    as = count haystack

where块中为count调用的结果指定一个名称意味着每次调用multirepeats时只计算一次(至少在使用GHC时)。
如果你想检查是否有 any 重复字符,你可以像这样重用count

anyRepeats :: Ord a => [a] -> Bool
anyRepeats = any (>=2) . count

或者,如果先排序,则可以使用基于列表的操作直接执行此操作:

import Data.List

anyRepeats' :: Ord a => [a] -> Bool
anyRepeats' as = not $ null [() | _:_:_ <- group (sort as)]
0s0u357o

0s0u357o2#

在回顾了我的职能之后,我想出了解决办法

element :: Eq t => t -> [t] -> Bool
element _[] = False
element x (y : ys) = if x == y then elem x ys else element x ys

如果特定值重复,则布尔值输出应为True:

element '.'"ban.nan."
True
lo8azlld

lo8azlld3#

我还得到了所需解决方案输出:

repeatedLocal :: [Char] -> Bool
repeatedLocal [] = False
repeatedLocal [_] = False
repeatedLocal (x:xs) = if elem x ['.', '_'] then True else repeated xs

相关问题