鱼C论坛

 找回密码
 立即注册
查看: 2872|回复: 3

[技术交流] 23 - 逆序数字/字符串

[复制链接]
发表于 2021-8-29 18:11:20 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 鱼C-小师妹 于 2022-2-22 15:44 编辑

在线讲解:



经过前面 3 讲的铺垫,相信童鞋们对递归应该很有感觉了!

除了递归三定律,其实递归问题无非就是这两类:

  • 数值问题
  • 非数值问题

数值问题的递归是指可以表达为数学公式的问题,例如 21 和 22 讲。

非数值问题的递归是指问题本身难以用数学公式来表达的问题,例如汉诺塔~

对于数值问题,由于本身可以表达为数学公式,所以可以从数学公式入手来推导出问题的递归定义,然后确定问题的边界条件,从而最终确定递归函数和递归结束条件。

对于非数值问题,由于其本身不能用数学公式来表达,因此其求解的一般方法是要自行设计一种算法,进而找到解决问题的一系列操作步骤。

如果能够找到解决问题的一系列递归操作步骤,则非数值问题也可以使用递归方法来求解。

通常数值问题的递归比较多,这一讲让我们趁热打铁,再来用递归解决一个整数逆序输出问题。

就是将任意输入的整数逆序输出,不能使用现成的逆序方法,像:

reverse()、list[::-1] 、reversed()

这几个方法小甲鱼老师在新版 Python 的 20~26 讲都介绍过了。

因此,首先要判断输入的整数是正整数还是负整数。

无论正负,程序都应该能处理。

如果是负整数,则在逆序输出前应先打印出负号。

接着解决整数的逆序问题。

假设输入的整数保存在变量 num 中,我们以输入 4 位的正整数为例。

其他位数的整数可类似地分析。

假设输入的 4 位正整数为 abcd。

我们可以这样拆开考虑:

    ● 基于四位数 abcd,如果前三位数 abc 已经实现了逆序成了 cba,则只需打印最后一位 d 与 cba 即可。
    ● 基于三位数 abc,如果前两位数 ab 已经实现了逆序成了 ba,则只需打印 c 与 ba 即可。
    ● 基于两位数 ab,如果前一位数 a 已经实现了逆序,则只需打印 b 与 a 逆序后的一位数即可,显然,a 逆序后还是它本身,因此此步可直接打印结果:ba 。
    ● 接着再由第 3 步向前递推,则可以实现逆序输出 abcd 这个四位整数。

由上面的分析过程可知,这是一个递归问题,将大问题逐渐细化,递归的出口就是对一位数进行逆序操作的结果仍是它本身。

刚才说的这句话算是递归的精髓了,我们再重复一遍:

将大问题逐渐细化,递归的出口就是对一位数进行逆序操作的结果仍是它本身。

根据上面的算法分析过程,先创建个负责逆序功能的递归函数 myReverse()。

主要就是用来去掉当前正整数 n 中的最高位,将剩下的正整数作为递归函数的实际参数:
def myReverse(n):
    if n != 0:
        print(f"{(n % 10)}",end="")
        myReverse(n // 10)
此外整数也包括负数对不对,我们就需要去掉符号“-”,然后再按照上面的递归操作。

怎么去掉符号呢?

就需要先把 num 转化字符串,截取第一位 “-”,然后将数字逆序,再拼接上。

截取直接 [1:] 就好,详细玩法看上面小甲鱼老师的课程:
num = int(input("请童鞋输入一个整数:"))
if num < 0:
    str_num = str(num)        
    num = str_num[1:]                 
    print("-",end="")        
    myReverse(int(num))    
else:        
    myReverse(num)
我们启动程序测试下:

2021-09-07_19-20-52.jpg

没问题实现我们的需求了,代码你们自己去写!
(源码: py23.py.zip (654 Bytes, 下载次数: 7, 售价: 8 鱼币)

我知道有的童鞋一定会问:字符串可以手动实现逆序吗?

既然数字都实现了,字符串一定也可以~

我们先直接使用递归来逆序输出字符串,和上面代码类似,以童鞋们现在的水平,就不解释啦:
def rvstr(s):
    if len(s) <= 1:
        return s
    return rvstr(s[1:]) + s[0]


if __name__ == "__main__":
    str = str(input("请输入一个字符串:"))
    str_result = rvstr(str)
    print(f"{str}逆序后{str_result}")
结果:

2021-09-14_19-43-05.jpg

在递归函数 rvstr(s) 中,我们用到了字符串的分片功能,通过递归调用字符串 s 的分片剪切实现字符串的逆序功能。

在 Py 中,一个字符串相当于一个不可改变序列的列表。

一旦这个字符串被定义了,则该字符串中的每个字符都有了自己确定的位置,也有了自己的下标,不可改变。

可以使用 “[]” 来访问字符串中指定位置上的字符,这种方式类似于 C 语言或 Java 语言中的数组。

详细玩法去看小甲鱼老师的最新版 Py 教程啦!

好的,下课!

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-20 22:15:57 | 显示全部楼层
一开始我是这样写的:
def reverse(n):
    if n // 10 == 0:
        return n
    else:
        return ((n % 10) + reverse(n // 10))
把数直接当字符串连起来了,实际上是数值相加。
def reverse(n):
    if n // 10 == 0:
        return n
    else:
        print(f"{(n % 10)}",end="")
        reverse(n // 10)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-2-28 19:43:33 | 显示全部楼层
小师妹讲的真好看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-12 15:43:47 | 显示全部楼层
# 迭代法
def reverseint(N):
    if '-' in N:
        output = '-'
        N = N[1:]
    else:
        output = ''
    index = len(N)-1
    while index >= 0:
        output += N[index]
        index -= 1
    return output
N = str(input('请输入:'))
print(reverseint(N))



# 递归法
def Reverse(N):
    index = len(N)
    if index <= 1:
        return N
    else:
        return N[index-1] + Reverse(N[:index-1])
N = str(input('请输入:'))
if '-' in N:
    output = '-'
    N = N[1:]
else:
    output = ''
output += Reverse(N)
print(output)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-18 08:52

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表