繁体   English   中英

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

[英]Return Bool if a specific value repeats

我目前正在为学校做一个关于 email 标识的项目,但是代码的某个部分我已经被卡住了很长一段时间,我一直在试图弄清楚如果某个值会重复我该如何返回Bool .

这是我当前的代码:

这个想法是建立一个 function 来搜索某个值是否重复

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)

预期的 output 是这样的:特殊的“penuts..” True

查看我的 function 后,我找到了解决方案

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

如果特定值重复,则 boolean 值 output 应为 True:

element '.'"ban.nan."
True

现在您有了解决方案,所以我不觉得我正在破坏良好的学习体验,这里有一些您可能会喜欢的额外实施想法。

如果您想检查单个字符的重复状态,您可以只询问该字符的副本,然后检查是否有两个(或更多)副本。

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 时)。

如果你想检查是否有任何重复字符,你可以像这样重用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)]

我也得到了我想要的解决方案 output:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM