python数据结构与算法 21 递归的实现和应用
2014-03-25 15:50
519 查看
把一个整数变成一个任意进制的字符串
假设你要把一个整数转变成一个从2到16进制的数字组成的字符串,例如,把整数10变成十进制是“10”,二进制就是“1010”。虽然很多算法能够实现,包括在栈的应用中我们讨论过一个算法,但是递归的算法仍然是最简洁的。先来看个例子,十进制数769。我们有一个字符串,含有10个数字的字符串,类似covString=”0123456789”。那么把一个小于10的数字变成串很简单,如果是数字9,字符串就是convString[9]或“9”。如果我们769分解成3个单数,就是7,6和9,然后分别转成字符串,这样小于10的数字转起来很简单。
估计基点算法要包括三个部分
1. 把原数字转成一串的个位数
2. 把个位数查表转成单个数的字符串
3. 把各个字符串合并
下一步就要考虑怎样改变状态趋向基点。既然处理对象是整数,我们来看一下在数学上是怎么办的。最可能选项是减法和除法,减法也许能行?拿什么减什么呢?不太清楚。然而除法和余数的想法给了一个明确的方向。来看一下,如果用基数来除整数,是什么情况.
用整数10去除769,得到76余9,得到两个数。首先,余数9是小于基数(10)的个位数,能够通过查表迅速转成字符串。其次,得到的商(76)小于原来的769,并朝向基点变动.现在的工作是把76变成字符串,再次用10去除76,得到7余6,现在我们把数字变成了个位数7,小于基数10,可以很容易处理成字符串。
这一连串的操作如图3所示,注意我们要的数字是图解右边的余数。
图3:转换整数为十进制字符串
代码段是算法的实现,基数可以是2-16之间的整数。
def toStr(n,base): convertString = "0123456789ABCDEF" ifn<base: returnconvertString else: returntoStr(n//base,base)+convertString[n%base] print(toStr(1453,16))
注意第3行我们检查n是否小于进制的基数,,如果是,不用递归,直接从字符串上获得结果。第6行包括了第二和第三定律——自我调用和趋向基点改变状态——使用除法。
我们再跟踪一次算法,这次转化数字10为二进制。
图4整数10转为二进制字符串
图4所示为求得结果的过程,但是看起来顺序似乎不对,但是计算结果又是对的。这是因为我们的递归计算放在前面,这样直到递归结束才会去加余数。如果我们把convertString[n%base]这个式子放在前面,先查找余数的字符串再去计算递归,那么结果就完全反了顺序!但是我们先做递归,直接递归结束返回结果再去和余数相加,结果的顺序就是正确的。这应该让你想起我们在讨论栈时候计算的过程。
堆栈帧:递归的实现
假设我们要把上节递归调用中的toStr和convertString换一下位置,就要修改算法,把字符串压栈,以优先做递归调用。这个修改后的算法如下:frompythonds.basic.stackimportStack rStack = Stack() deftoStr(n,base): convertString ="0123456789ABCDEF" whilen>0: ifn<base: rStack.push(convertString ) else: rStack.push(convertString[n%base]) n = n//base res = "" whilenotrStack.isEmpty(): res = res+str(rStack.pop()) returnres print(toStr(1453,16))
每次调用toStr,我们都把一个字符压栈。回到此前的例子,我们看到经过四次调用toStr,栈内容如图5所示。注意现在我们可以简单地把字符出栈并合并成为答案:“1010”。
图5转化过程中栈内的字符
这个例子让我们得以窥到python是如何实现递归函数调用的。当调用一次函数,系统分配一个堆栈帧来存储函数的变量,当函数返回时,返回值就存在栈顶等待调用函数访问。图6所示是第4行返回语句之后的调用栈情况。
图6 toStr(10,2)产生的调用栈
注意对toStr(2//2,2)的调用,留下“1”在栈内,这个值陏后在调用toStr(1,2)时,表达式"1" + convertString[2%2]用到。然后它又留下"10"在栈顶。这样,python调用栈的过程和我们在递归求和时所有过程明显一样。在求和算法中,你可以认为栈内返回值替换了累加器变量。
堆栈帧也提示了python语言变量作用域的概念,虽然我们一遍又一遍调用函数,但每次都为函数变量开辟了独立的变量作用域。
如果牢牢记住这个栈的思想,你将会发现写递归函数变得容易多了。
相关文章推荐
- 数据结构(21)栈与递归应用之汉诺塔递归实现
- python数据结构与算法 10 栈的应用之中缀转后缀表达式算法的实现
- python应用之二分递归实现sqrt,递归实现快排
- Python递归实现汉诺塔
- Python练习(1):递归和动态规划的简单应用
- 《数据结构与算法》学习笔记21 递归_消除递归
- Python的迭代和递归实现菲波那切数列(Fibonacci sequence)
- Python利用递归实现文件的复制方法
- 最近在研究enigma2的代码,那叫个庞大,C/C++写中间件,上层应用全部用python实现,可以学习一下plugin的实现机制了.
- python 全排列 递归中的两种实现
- 数学趣题——应用递归实现数制转换
- 数据结构学习之-二叉树的三种递归遍历C++实现及相关应用
- Fibonacci(斐波那契)数列的递归与非递归实现 python
- Python递归实现汉诺塔详细解析
- 兔子生娃问题---函数递归应用--c语言实现
- Python实现的数据结构与算法之快速排序详解
- 用Python实现的数据结构与算法:基本搜索
- 用Python实现的数据结构与算法:快速排序
- 数据结构与算法之链表的Python简单实现
- 深入理解Python中协程的应用机制: 使用纯Python来实现一个操作系统吧!!