细聊递归(二)|Go主题月

198 阅读2分钟

细聊递归(一)|Go主题月中介绍了递归函数的基本思想和通过递归来求切片数据之和。
现在尝试另外一个问题:
把一个十进制整数转换为2-16为基数的任意进制字符串。例如,255转换为十进制的255,二进制的11111111,八进制的377。

当你看完本文,你会惊叹递归是多么的优雅!

以1234转换为十进制字符串为例。我们这里需要一个字符序列对应前16个数:

strMap := "0123456789ABCDEF"

如果要将一个小于16的数字转换为字符串,只需要在strMap字符序列中查找对应的数字即可。例如, 2对应的字符串是strMap[2]即"9"。

那么,如果能把整数1234拆分成1、2、3和4,那么根据strMap将其转换为字符串就可以了。所以,基本情况即函数停止递归的条件就是数字小于其进制基数,此例子为小于10。

所以,整个算法包含三个组成部分:

  1. 将原来的整数分成一系列仅有单数位的数;
  2. 根据strMap将数字转换为对应的字符串;
  3. 拼接字符串

那么,什么方法可以缩减整数?除法
那么,如何获得一位数呢并且是整数逐步缩小到只有一位数? 除以进制

例如,1234除以10, 商是123, 余数是4。余数就是我们需要转换成字符串的数字,商被缩短了。
那么,下一步就是求123对应的字符串了。再一次运用除法,得到余数3和商12。
下一步,再一次运用除法,得到余数2和商1。
下一步,因为商1<进制10,满足基本情况,停止递归。

用Golang代码实现如下:

package main

import "fmt"

func toStr(num int, base int) string {
	// 将十进制整数转换为2-16为基数的进制字符串
	mapStr := "0123456789ABCDEF"
	if num < base {
		return string(mapStr[num])
	} else {
		return toStr(num/base, base) + string(mapStr[num%base])
	}
}


func main() {
	fmt.Println(toStr(1234, 10))
}