You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell合并八进制校验与转十进制功能,单函数实现非法输入返0

实现方案

首先你现有代码有两处需要修正的问题:

  • 你写的isOcto校验逻辑有误:八进制合法字符范围是0~7,但你的判断条件digitToInt(x) > 0 && digitToInt(x) < 7只允许1~6的字符,漏掉了0和7两个合法值
  • 没有判断输入字符是否为数字,直接调用digitToInt处理非数字字符会抛出运行时异常

方案1:先校验后转换(逻辑清晰易读)

直接在校验通过后执行转换逻辑,非法输入直接返回0:

import Data.Char (digitToInt, isDigit)

octoDec :: [Char] -> Int
octoDec s = if isOcto s then convert s else 0
  where
    -- 修正后的合法校验逻辑
    isOcto [] = True
    isOcto (x:xs) = isDigit x && let d = digitToInt x in d >= 0 && d <= 7 && isOcto xs
    -- 原有转换逻辑
    convert [] = 0
    convert (x:xs) = digitToInt x * 8 ^ length xs + convert xs

方案2:单次遍历实现(效率更高)

不需要分两次遍历字符串(一次校验一次转换),用折叠操作在单次遍历中同时完成校验和转换,遇到非法字符直接返回0:

import Data.Char (digitToInt, isDigit)

octoDec :: [Char] -> Int
octoDec = fst . foldl process (0, True)
  where
    process (res, isValid) c
      | not isValid = (0, False) -- 已经判定非法,直接保持状态
      | not (isDigit c) || d < 0 || d > 7 = (0, False) -- 遇到非法字符
      | otherwise = (res * 8 + d, True) -- 正常计算十进制值
      where d = digitToInt c

两种方案都满足需求:输入合法八进制字符串返回对应十进制值,输入包含非法字符时返回0。

内容的提问来源于stack exchange,提问作者Eduardo Machado

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 18:24:05