Haskell实现1-61进制任意互转功能的代码问题求助
你现有的实现存在几个明显的问题需要调整:
- 函数签名不符合需求:
toDecimal返回值为Int、fromDecimal入参为Int,都要求是字符串格式 - 缺失边界校验:没有处理进制1、进制超过61、输入为0的特殊情况
- 字符转数值的逻辑冗余,长串转换效率偏低
- 没有实现第三个进制直接转换的函数
下面是符合要求的完整实现,仅依赖base标准库:
import Data.List (elemIndex) import Data.Maybe (fromMaybe) -- 公共字符集:下标对应字符的数值,范围0-61 digits :: String digits = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" -- 1. 指定进制字符串转十进制字符串 toDecimal :: Int -> String -> String toDecimal base snumber | base < 1 || base > 61 = error "进制范围必须为1-61" -- 处理1进制:规则为n个'1'对应十进制n | base == 1 = if all (=='1') snumber then show (length snumber) else error "1进制仅允许字符'1'" -- 其他进制按权累加 | otherwise = show $ foldl (\acc c -> acc * base + charToInt c) 0 snumber where charToInt :: Char -> Int charToInt c = fromMaybe (error "输入包含非法字符") $ elemIndex c digits -- 2. 十进制字符串转指定1-61进制字符串 fromDecimal :: Int -> String -> String fromDecimal toBase snumber | toBase < 1 || toBase > 61 = error "进制范围必须为1-61" | num < 0 = error "不支持负数转换" -- 处理0的特殊情况 | num == 0 = "0" -- 处理1进制:返回对应数量的'1' | toBase == 1 = replicate (fromIntegral num) '1' -- 其他进制除基取余拼接 | otherwise = reverse $ go num where num = read snumber :: Integer go 0 = [] go n = digits !! fromIntegral (n `mod` toInteger toBase) : go (n `div` toInteger toBase) -- 3. 任意两种进制直接转换 convertFromTo :: Int -> Int -> String -> String convertFromTo fromBase toBase snumber = fromDecimal toBase $ toDecimal fromBase snumber
补充说明:
- 1进制采用图灵机常用的表示规则:数值n对应n个连续的'1',输入仅允许'1'字符
- 数值类型使用Integer避免Int溢出问题,支持大数值转换
- 字符映射严格遵循你原有的规则:数字0-9对应0-9,小写a-z对应10-35,大写A-Z对应36-61
- 所有入参都做了合法性校验,非法输入会直接抛出明确的错误提示
内容的提问来源于stack exchange,提问作者user17221096
相关产品推荐
相关产品推荐

