P95 - 英文数字单词

2026-09-07 00:00    #Haskell   #99题   #字符串  

P95 - 英文数字单词

English number words

官方模块:Problems.P95 核心函数:fullWords


← P94 正则图 | P96 Ada 标识符 →


题目描述

把非负整数逐位转换为英文单词,并用连字符连接。题目不是把 175 写成 “one hundred seventy-five”,而是 one-seven-five

实现

方法一:算术拆分数字

 1import Data.List (intercalate)
 2
 3fullWords :: Integral a => a -> String
 4fullWords n
 5  | n < 0     = error "fullWords: non-negative input required"
 6  | n == 0    = "zero"
 7  | otherwise = intercalate "-" (map digitWord (digits n))
 8
 9digits :: Integral a => a -> [Int]
10digits 0 = []
11digits n = digits (n `div` 10) ++ [fromIntegral (n `mod` 10)]
12
13digitWord 0 = "zero"
14digitWord 1 = "one"
15digitWord 2 = "two"
16digitWord 3 = "three"
17digitWord 4 = "four"
18digitWord 5 = "five"
19digitWord 6 = "six"
20digitWord 7 = "seven"
21digitWord 8 = "eight"
22digitWord 9 = "nine"
23digitWord _ = error "digitWord: not a digit"

方法二:复用十进制 show

1fullWordsViaShow :: Integral a => a -> String
2fullWordsViaShow n
3  | n < 0     = error "fullWords: non-negative input required"
4  | otherwise = intercalate "-"
5      [digitWord (fromEnum c - fromEnum '0') | c <- show (toInteger n)]

show 已经完成十进制位的提取,并且会为 0 产生字符串 "0"。随后只需把每个字符转换成数字下标并查单词。

方法对比

方法数位来源
算术拆分反复执行 divmod
show复用标准十进制格式化

测试

1>>> fullWords 175
2"one-seven-five"
3>>> fullWords 0
4"zero"
5>>> fullWords 1002
6"one-zero-zero-two"
7>>> fullWordsViaShow 1002
8"one-zero-zero-two"

digits 中的尾部 ++ 对位数很少的整数足够清楚;也可用累加器一次生成正序数字。

参考


← P94 正则图 | P96 Ada 标识符 →