如何在SML中递归实现整数(int)到字符串(string)的转换
SML 递归实现 int 转 string 的方案
你当前的非递归实现是直接调用标准库的Int.toString完成核心转换,要做成纯递归实现,核心是跳过标准库的字符串转换能力,自己拆分整数的每一位数字,逐位拼接成字符串,逻辑可以拆解为以下步骤:
核心实现逻辑
- 先实现单个数字(0-9范围)的字符映射:利用SML的
chr和ord内置函数,把数字值映射为对应的数字字符,比如数字3对应字符#"3",转换后拼接为单字符字符串即可,不需要手动硬编码0-9的字符串映射表 - 写专门处理非负整数的递归转换逻辑:
- 递归出口:当待转换的数值小于10时,直接返回该数值对应的单字符字符串
- 递归分支:把数值拆为两部分——整除10得到的高位数、对10取余得到的个位数;高位数递归执行转换逻辑,最后和个位数对应的字符串拼接即可
- 负数的处理逻辑和你现有非递归版本保持一致:检测到传入值为负时,先对数值取绝对值,递归执行非负整数的转换,最后在结果前拼接负号标记
"~"即可
完整可运行递归代码
(* 0-9单数字转对应字符串 *) fun digit2str d = str (chr (ord #"0" + d)) (* 非负整数递归转字符串辅助逻辑 *) fun posInt2str n = let fun aux 0 = "" | aux k = aux (k div 10) ^ digit2str (k mod 10) in (* 单独处理n=0的边界情况,避免返回空串 *) if n = 0 then "0" else aux n end (* 对外暴露的主转换函数 *) fun int2str i = if i < 0 then "~" ^ posInt2str (~i) else posInt2str i
效果验证
- 调用
int2str (~1234)会返回"~1234" - 调用
int2str (1234)会返回"1234" - 调用
int2str (0)会返回"0",覆盖了原非递归版本没处理的0值边界
常见踩坑点
- 不要把负数直接传入位拆分的递归逻辑:SML的
mod和div对负数操作时会产生负的余数,会导致拼出的字符ASCII值不在数字字符范围内,出现乱码 - 必须单独覆盖0值的递归边界:如果让递归处理0值的时候走正常分支,会因为不断整除10直到值为0,最终返回空字符串,和实际预期不符
- 负号处理不需要嵌入到每一位的递归逻辑里:之前你写字符串转int时被开头的
"~"干扰,转字符串的时候只要把负号的判断放在最外层,就不会出现递归过程中重复处理负号的问题
内容的提问来源于stack exchange,提问作者mrdc1790
相关产品推荐
相关产品推荐

