Haskell 函数将 Int 转换为 alpha numerotation [关闭]
Posted
技术标签:
【中文标题】Haskell 函数将 Int 转换为 alpha numerotation [关闭]【英文标题】:Haskell function to convert Int to alpha numerotation [closed] 【发布时间】:2019-08-30 16:01:59 【问题描述】:我正在尝试编写一个 Haskell 函数来将整数转换为带有字母数字循环的字符串。
通过字母数字,我的意思是与此转换匹配的数字:
1 -> A
2 -> B
3 -> C
..
25 -> Y
26 -> Z
27 -> AA
28 -> AB
29 -> AC
..
我发现这个function 可以将十进制数字转换为罗马数字,并尝试对其进行修改以做我想做的事情。但我没有设法得到正确的结果。问题是在字母计数中,“A”在用作单位或倍数时具有不同的“权重”(它可以是 1 或 0)。
你知道如何获得正确的转换吗?
【问题讨论】:
您正在转换为基数 26,其中数字是字母 A-Z。 什么,不为零?只有正面? 是的,这个功能是重现Office计算列中使用的数字,LaTeX/html章节编号(counter(subsection,upper-alpha)
)
这很容易出错,因为它非常类似于转换为base 26,但在第一个字母上有细微的差别。在基数 26 中,第一个数字的范围从 1
到 25
,而所有其他数字的范围从 0
到 25
。相反,在上面的枚举中,所有字母的范围从A
到Z
。
@chi 你说得对,我没有意识到这个微妙之处。我会弄错的。
【参考方案1】:
使用模运算非常容易。我们将编写一个以相反顺序返回字母的函数;之后我们可以在顶层修复它。基本思想是反复除以 26。所以:
rawCellName :: Int -> String
rawCellName x | x <= 0 = []
rawCellName x = toEnum (fromEnum 'A' + r) : rawCellName q where
(q, r) = (x-1) `quotRem` 26
然后在顶层我们只是修复 API 的奇怪之处:
cellName :: Int -> String
cellName = reverse . rawCellName
在 ghci 中尝试一下:
> map cellName [1..5]
["A","B","C","D","E"]
> map cellName [25..30]
["Y","Z","AA","AB","AC","AD"]
【讨论】:
【参考方案2】:这里我们可以先将数字转化为数字序列,每次除以26,然后取模:
import Data.List(unfoldr)
toColumnName :: Int -> String
toColumnName = reverse . fmap (toEnum . (64+)) . unfoldr f
where f 0 = Nothing
f n = Just ((mod (n-1) 26)+1, div (n-1) 26)
或更短:
import Data.List(unfoldr)
import Data.Tuple(swap)
toColumnName :: Int -> String
toColumnName = reverse . fmap (toEnum . (65+)) . unfoldr f
where f 0 = Nothing
f n = Just (swap (divMod (n-1) 26))
例如:
Prelude Data.List> map toColumnName [1..100]
["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","AA","AB","AC","AD","AE","AF","AG","AH","AI","AJ","AK","AL","AM","AN","AO","AP","AQ","AR","AS","AT","AU","AV","AW","AX","AY","AZ","BA","BB","BC","BD","BE","BF","BG","BH","BI","BJ","BK","BL","BM","BN","BO","BP","BQ","BR","BS","BT","BU","BV","BW","BX","BY","BZ","CA","CB","CC","CD","CE","CF","CG","CH","CI","CJ","CK","CL","CM","CN","CO","CP","CQ","CR","CS","CT","CU","CV"]
【讨论】:
以上是关于Haskell 函数将 Int 转换为 alpha numerotation [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
Haskell:如何将 IO 输入字符串解析为 Float(或 Int 或其他)?