Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将大写字母转换为小写字母,并计算Haskell中的字符串_Haskell - Fatal编程技术网

将大写字母转换为小写字母,并计算Haskell中的字符串

将大写字母转换为小写字母,并计算Haskell中的字符串,haskell,Haskell,我是Haskell的新手,我正在尝试将输入的字符串转换为小写字母。转换后,我想对所有来自['a'..'z']的小写字母进行计数 例如:“这是一个TES3T” 结果:[(t,3)、(h,1)、(i,2)、(s,2)、(a,1)(e,1)] 这就是我到目前为止所做的: countL :: [Char] -> Char -> Int countL s c = length ( [x | x <- s, x == c]) letter_count :: [Char] -> [(

我是Haskell的新手,我正在尝试将输入的字符串转换为小写字母。转换后,我想对所有来自['a'..'z']的小写字母进行计数

例如:“这是一个TES3T” 结果:[(t,3)、(h,1)、(i,2)、(s,2)、(a,1)(e,1)]

这就是我到目前为止所做的:

countL :: [Char] -> Char -> Int
countL s c = length ( [x | x <- s, x == c])

letter_count :: [Char] -> [(Char, Int)]
letter_count s = nub [(c, countL s c) | c <- s]
countL::[Char]->Char->Int
countL s c=长度([x | x[(字符,整数)]
字母_counts=nub[(c,countL s c)| c[Char]

toLowerString str=[toLower x | x解决方案中有一些优化空间


首先函数
letter_count
在O(n^2)时间内运行:当
[(c,countL s c)| c的结果出现时,解决方案中有一些优化空间


首先函数
letter_count
在O(n^2)时间内运行:当
[(c,countL s c)| c的结果出现时,使用模块
Data.List中的函数
group
()。它接受一个列表并返回其分组元素的列表。要获得唯一的组,只需先对输入字符串排序。例如:

group (sort "Hello World")
将为您提供:

[" ","H","W","d","e","lll","oo","r"]
您只需将这些子字符串中的每一个子字符串转换为其长度和第一个字母的元组:

map (\s -> (head s, length s))
因此,您的
字母计数将是:

letter_count :: [Char] -> [(Char, Int)]
letter_count = map (\s -> (head s, length s)) . group . sort

计数字母的一个简单易行的方法是使用模块
Data.List
()中的函数
group
。它获取一个列表并返回其分组元素的列表。要获得唯一的组,只需先对输入字符串排序。例如:

group (sort "Hello World")
将为您提供:

[" ","H","W","d","e","lll","oo","r"]
您只需将这些子字符串中的每一个子字符串转换为其长度和第一个字母的元组:

map (\s -> (head s, length s))
因此,您的
字母计数将是:

letter_count :: [Char] -> [(Char, Int)]
letter_count = map (\s -> (head s, length s)) . group . sort

Radek提到的阵列解决方案如下所示:

toLowerString :: [Char] -> [Char]
toLowerString str = map toLower str
    groupedStr = (group . sort . map toLower . filter isLetter) str
import qualified Data.Array.Unboxed as A
import Data.Char ( isAsciiLower )

countLettersArr :: [Char] -> [(Char, Int)]
countLettersArr cs = filter ((/= 0) . snd) (A.assocs arr)
  where
    arr :: A.UArray Char Int
    arr = A.accumArray (+) 0 ('a', 'z')
          [(c, 1 :: Int) | c <- cs, isAsciiLower c]
一种效率稍低的方法是使用
IntMap
而不是数组。这有点痛苦,因为
IntMap
只接受
Int
索引,但其工作方式几乎相同:
fromListWith
accumArray
非常相似。此版本将记录您输入的任何字符不管是否使用小写字母。您可以通过在
im
定义中的列表理解中添加一个保护来轻松改变这一点

import qualified Data.IntMap.Strict as M
import Data.Char (ord, chr)
import Data.Bifunctor (first)

-- Count how many of each letter appear in a string.
countLettersIM :: [Char] -> [(Char, Int)]
countLettersIM cs = map (first chr) . M.toList $ im
  where
    im :: M.IntMap Int
    im = M.fromListWith (+) [(ord c, 1) | c <- cs]
import qualified Data.IntMap.Strict作为M
导入数据.Char(ord,chr)
导入数据.Bifunctor(第一个)
--计算每个字母在一个字符串中出现的数量。
countLettersIM::[Char]->[(Char,Int)]
countlettsim cs=map(第一个chr).M.toList$im
哪里
im::M.IntMap Int
im=M.fromListWith(+)[(ord c,1)| c[a]->[(a,Int)]
countEnumsIM cs=map(first-toEnum).M.toList$im
哪里

im=M.fromListWith(+)[(fromnum c,1)| cRadek提到的阵列解决方案如下所示:

toLowerString :: [Char] -> [Char]
toLowerString str = map toLower str
    groupedStr = (group . sort . map toLower . filter isLetter) str
import qualified Data.Array.Unboxed as A
import Data.Char ( isAsciiLower )

countLettersArr :: [Char] -> [(Char, Int)]
countLettersArr cs = filter ((/= 0) . snd) (A.assocs arr)
  where
    arr :: A.UArray Char Int
    arr = A.accumArray (+) 0 ('a', 'z')
          [(c, 1 :: Int) | c <- cs, isAsciiLower c]
一种效率稍低的方法是使用
IntMap
而不是数组。这有点痛苦,因为
IntMap
只接受
Int
索引,但其工作方式几乎相同:
fromListWith
accumArray
非常相似。此版本将记录您输入的任何字符不管是否使用小写字母。您可以通过在
im
定义中的列表理解中添加一个保护来轻松改变这一点

import qualified Data.IntMap.Strict as M
import Data.Char (ord, chr)
import Data.Bifunctor (first)

-- Count how many of each letter appear in a string.
countLettersIM :: [Char] -> [(Char, Int)]
countLettersIM cs = map (first chr) . M.toList $ im
  where
    im :: M.IntMap Int
    im = M.fromListWith (+) [(ord c, 1) | c <- cs]
import qualified Data.IntMap.Strict作为M
导入数据.Char(ord,chr)
导入数据.Bifunctor(第一个)
--计算每个字母在一个字符串中出现的数量。
countLettersIM::[Char]->[(Char,Int)]
countlettsim cs=map(第一个chr).M.toList$im
哪里
im::M.IntMap Int
im=M.fromListWith(+)[(ord c,1)| c[a]->[(a,Int)]
countEnumsIM cs=map(first-toEnum).M.toList$im
哪里

im=M.fromListWith(+)[(fromnum c,1)| c Try
toLowerAndFilterString=filter(`elem`['a'..'z'])。映射到lower
.fyi,
Data.List.Utils.countElem
Try
toLowerAndFilterString=filter(`elem`['a'..'z'])).map toLower
.fyi,
Data.List.Utils.countElem
从列表理解转换为
map
不是一种优化;编译后的代码(以及性能)应该是相同的。但更清楚。你是对的,我的意思是。也许我不够清楚。感谢@Radek的非常好的解释。如果我决定使用百分比而不是计数。即。[(t,0.25),(h,0.12)]如t=25%和h=12%。我可以使用类似的方法吗?当必须将函数组合在一起时,我感到困惑,而且您的方法似乎非常清楚。是的,您可以轻松修改我的解决方案来计算百分比。您想计算与字母数的字符总数相关的百分比吗?例如,
 aaaa1234
字母a应该得到50%或100%?如果你让我知道,我会扩展我的答案。简短的解释:要得到百分比,基本上你所要做的就是计算
str
filteredStr
的长度(取决于你是否想要考虑非字母符号——50%对100%以上):
lengthOfStr=length str
然后将最后一个表达式修改如下:
[(h,from integral(length fragment)/lengthOfStr)| fragment@(h:_)从列表理解切换到
map
不是优化;编译后的代码(以及性能)应该是相同的。但更清楚。你是对的,我的意思是。也许我不够清楚。感谢@Radek的非常好的解释。如果我决定使用百分比而不是计数。即。[(t,0.25),(h,0.12)]如t=25%和h=12%。我可以使用类似的方法吗?当必须将函数组合在一起时,我感到困惑,而且您的方法似乎非常清楚。是的,您可以轻松修改我的解决方案来计算百分比。是否要计算与函数的总字符数相关的百分比
countEnumsIM :: Enum a => [a] -> [(a, Int)]
countEnumsIM cs = map (first toEnum) . M.toList $ im
  where
    im = M.fromListWith (+) [(fromEnum c,1) | c <- cs]