【问题标题】:Haskell case statements with ord 'x'带有 ord 'x' 的 Haskell 案例陈述
【发布时间】:2018-10-11 20:26:47
【问题描述】:
import Data.Char  
x1 xs = sum(map (hilfsfunction) xs)
hilfsfunction x  
   | (ord 'x' > 97 && ord 'x' < 107) = (ord 'x' - 96)  
   | (ord 'x' > 48 && ord 'x' < 58) = (ord 'x' - 48)  
   | otherwise = 0  

我需要编写一个程序,其中函数接受一个字符串,然后用它做以下事情:
- 如果字母是 a,则将其更改为 1
- 如果这封信是别的东西,我应该取相同的数字。
- 所有其他符号应更改为 0

我现在的问题是,每次我启动这个程序时,总和都是 0,不管第一种情况还是第二种情况是真的。

示例:让我们取“6”:

*Main Data.Char> ord '6' > 48 && ord '6' < 58
True

之后:

*Main Data.Char> ord '6' - 48
6

但如果我承担我的职责,每次都是这样......:

*Main Data.Char> x1 "6"
[0]

我不知道我的错误在哪里。

【问题讨论】:

  • 你硬编码了 'x' 字符而不是使用 x 变量我猜。
  • 调整警告会发现错误。我建议这样做,并解决每个警告,尤其是那些报告缺少类型签名的警告。

标签: string haskell sum case


【解决方案1】:

您在这里硬编码了'x' 字符,而不是使用x 变量

import Data.Char  
x1 xs = sum(map (hilfsfunction) xs)
hilfsfunction x  
   | (ord 'x' > 97 && ord 'x' < 107) = (ord 'x' - 96)  
   | (ord 'x' > 48 && ord 'x' < 58) = (ord 'x' - 48)  
   | otherwise = 0

这意味着 Haskell 并不关心 x 的值是什么:它只会使用 'x'

注意,这里你写了一个相当神秘的函数,你可以通过与其他字符比较来写得更简洁,并且在做算术时使用ord

hilfsfunction :: Char -> Int
hilfsfunction x  
   | 'a' <= x && x <= 'z' = ox - ord 'a' + 1
   | '0' <= x && x <= '9' = ox - ord '0'
   | otherwise = 0
    where ox = ord x

这里乍一看很清楚(不知道 ASCII 的轮廓),您首先检查x 是否在['a'..'z'] 范围内,如果是这种情况,您基本上使用它的序列号。如果不是,则检查它是否在['0' .. '9'] 范围内,然后使用其对应的数字,否则返回0。事实上,你在实现中犯了一个错误,因为ord 'z'122,而不是107。虽然您可以使用122,但通过与'z' 进行比较,它出错的可能性可能更小,因为您让Haskell 将字符转换为其等效的ASCII 代码。

使用hilsfsfunction 的新定义,我们得到:

Prelude Data.Char> x1 "6aa@a1a~dwfwf123"
79

【讨论】:

  • 谢谢,现在我理解并编辑了我的代码:)
【解决方案2】:

总和中有信息丢失。第一个'0' 不包括在内。其次,['1'..'9']['a'..'i']的范围在总和上是一样的。

另外,如果我要写这个,我会

import Data.Char (ord)
sol x | elem x ['0'..'9'] = mod (ord x) 16
      | elem x ['a'..'z'] = mod (ord x) 32
      | elem x ['A'..'Z'] = mod (ord x) 64
      | otherwise = 0

这样就可以证明前面的事实了

sol 'd' produces 4
sol '4' produces 4
sol '@' produces 0
sol '0' produces 0

话虽如此,ord 是 ASCII 字符集的索引。 可以只使用您感兴趣的字符创建您自己的索引。

tlz = zip [1..] $ concat [['0'..'9'],['a'..'z']]

然后您可以查找字符,每个字符都有一个唯一的索引号,即使是零“0”也会注册为一。如果一个字符不在表中,则根本不计算在内。列表压缩只会发出一个空的[]

创建以下函数以使用列表。输出比原函数大,tls的长度是36,原来是26。

smmat = sum.concat.map (\x->[a|(a,b)<-tlz,x == b])

只要给它一个列表。

smmat "This is 42% sure"

226

请放心,在前面的列表中有 11 个“命中”。将sum 从列表中取出以查看或将列表理解中的a 更改为 b 以查看字符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-30
    • 1970-01-01
    • 2023-04-10
    • 2010-10-30
    • 2016-05-13
    • 2016-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多