Pythonic:递归、回溯等5种方法生成不重复数字整数
问题描述:从0到9这10个数字任选3个不重复的数字,能构成哪些三位数?
So easy!看到这样的问题,很多人会写出类似(注意,只是类似,我为了使得本文几个函数具有相同的调用形式,给demo1和demo2加了点多余的东西)下面这样的代码:
def demo1(data, k=3):
'''从data中选择不同的3个数字组成三位数'''
assert k == 3, 'k must be 3'
for i in data:
if i == 0:continue
ii = i*100
for j in data:
if j == i:continue
jj = j * 10
for k in data:
if k!=i and k!=j:
print(ii + jj + k)
OK,这段代码确实能够满足题目的功能要求,但是好像有个小问题:在上面的代码中,先选择i,然后再依次选择j和k,如果选到重复数字就“放回去”重新选,有没有办法可以保证在选择的时候避免选到已有的数字呢?答案是确定的,请看下面的代码(感谢浙江温州永嘉县教师发展中心应根球老师提供的思路):
def demo2(data, k=3):
'''妙用集合实现同样功能'''
assert k == 3, 'k must be 3'
data = set(data)
for i in data:
if i == 0:continue
ii = i * 100
for j in data - {i}:
jj = j * 10
for k in data - {i, j}:
print(ii + jj + k)
上面这段代码首先把给定的数字序列转换为集合,然后每选择一个数字之后就把这个数字从集合中拿走,巧妙地避免了选择重复数字。
现在问题又来了:如果题目稍微修改一下,让选择4个不重复的数字组成4位数,肿么办?修改上面的代码,再增加一个嵌套的循环来选择第4个数?要是让选择8个呢?再改?很明显,这是不行的,做不到自适应的代码绝对不是好代码。
如果循环次数没法提前确定,如何才能做到选择任意个(当然小于等于10)不重复数字来组成整数呢?答案是递归和回溯。下面来看看这两段代码:
def demo3(data, k, s=()):
'''回溯法'''
if len(s) == k and s[0] != 0:
print(eval(''.join(map(str,s))))
res = []
for item in data:
if item in s:
continue
for r in demo3(data, k, s+(item,)):
res.append(r)
return res
def demo4(data, k, s=()):
'''递归法'''
if len(s) == k and s[0] != 0:
print(eval(''.join(map(str,s))))
else:
for item in data:
if item not in s:
demo4(data, k, s+(item,))
晕不晕?回溯法和递归法往往以代码简洁著称,但是在很多时候确实也比较难理解的。难道就真的没有更好的办法了吗?既然选择了Python,那就让我们写一个下面这样Pythonic的代码,不用递归,也不用回溯,并且能够实现选择任意个数字来组成整数,OMG!
def demo5(data, k):
'''使用枚举组合数的方法产生任意位数的数字'''
from itertools import permutations
r = permutations(data, k)
for item in r:
if item[0] != 0:
print(eval(''.join(map(str, item))))
然后就可以调用上面的函数来生成整数了:
data = range(10)
demo5(data, 5)
本文内容针对《Python程序设计基础》和《Python程序设计》(第2版)(董付国编著,清华大学出版社)两本教材中的例3-13进行拓展。
温馨提示:单击文章顶部作者名字旁边浅蓝色的“Python小屋”进入公众号,关注后可以查看更多内容!
欢迎转发给您的朋友,或许这正是Ta需要的知识!
Pythonic:递归、回溯等5种方法生成不重复数字整数相关推荐
- 递归和循环两种方法完成树的镜像转换
/* copyright@nciaebupt 转载出处:http://blog.csdn.net/nciaebupt/article/details/8506038 题目:输入一颗二元查找树,将该树转 ...
- 《 Python List列表全实例详解系列(四)》__列表删除元素(4种方法)删除重复元素(去重)(8种方法)
< Python List列表全实例详解系列(四)> __列表删除元素(4种方法)删除重复元素(去重)(8种方法) 我的技术成长&学习资料整理分享之路 我遇到问题查找资料时,经常 ...
- Excel如何快速生成不重复随机整数
日常工作中我们经常会遇到要生成随机数的情况,比如分考场.分班级.抽样.抽奖等等.下面就给大家介绍一下如何生成不重复随机数. 一.工具法 1.如下图是某学校考试座次表,姓名列已经完成,现在我们要在座次列 ...
- php创建不重复的7位数字,php如何生成不重复数字
php生成不重复数字的方法是:可以通过mt_rand()函数来实现.函数语法:[mt_rand(min,max)],例如[mt_rand(10,100)],表示生成一个介于10和100之间(包括10和 ...
- VBA实现两种方法生成任意概率分布的随机数
引子 一把武器的品质有分为最下级.下级.中级.上级.最上级五档,我希望在击杀一只怪物的时候,这把武器的掉率:最下级>下级>中级>上级>最上级,问如何设计满足上面的需求? 在游戏 ...
- mysql 随机取不重复数据_随机生成不重复数字,想做Excel抽奖器你必须掌握!
年会期间,大家最期待的便是抽奖环节了,只是有人欢喜有人忧,有的人连续几年每次都能抽中,有的人就像我一样,年年不中.... 人人概率相等,我觉得是不存在的 那如何用Excel做一个简易抽奖器呢?这个你必 ...
- C++ 随机数生成的2种方法--生成指定范围内的随机数
第一种是传统的方法: #include <iostream>using namespace std;int main() {srand(NULL);for (int i = 0; i &l ...
- 三种方法生成随机数之srand篇
srand()函数:随机数发生器的初始化函数,需要提供一个种子,这个种子会对应一个随机数.如果使用相同的种子,rand() 函数会出现一样的随机数.默认种子数是1,即srand(1). srand() ...
- treeview递归绑定的两种方法
方法一: public void creattree(int fid, TreeNode parentnode){DataTable dt = new DataTable();dt = op.Bind ...
最新文章
- 阿里云API网关(8)开发指南-SDK下载
- python中文乱码例子
- 使用LeakCanary遇到的问题 就是不弹出来
- 机器人学习--Imperial College London机器人学课程
- SAP Spartacus 里的 .release-it.json 文件
- 前端攻略系列(二) - 前端各种面试题
- 手把手教你入门Git --- Git使用指南(Linux)
- python中set函数是什么数据类型_Python基本数据类型之set
- 一文带你了解GaussDB(DWS) 的Roach逻辑备份实现原理
- 启用sharepoin2013中的ChartWebPart
- python循环语句输出_python循环语句
- python cad 二次开发bom_python处理BOM
- python全栈开发工程师_老男孩Python高级全栈开发工程师三期完整无加密带课件(共104天)...
- TensorFlow之saved_model使用笔记
- [电动智能汽车-3]:原理 - 整车控制器VCU功能
- 绘制一幅蓝图_给未来画一幅蓝图
- 《c语言程序设计》第一次网上作业,精编国家开放大学电大《C语言程序设计》《劳动与社会保障法》网络课形考网考作业(合集)答案...
- 组合数学 多重集的排列和组合
- C语言----小游戏
- 2018技术胖Web前端视频教程全套
热门文章
- mysql shell无法启动服务_[shell脚本] mysql服务启动脚本
- Java 虚拟机学习笔记 | 运行时数据区总结
- ReactNative绑定函数中的this
- java swing mysql实现的员工工资管理系统项目
- 基于JAVA+SpringMVC+Mybatis+MYSQL的养老社区管理系统
- 【JVM】Java虚拟机
- POJ-2456.Aggressivecows.(二分求解最大化最小值)
- Java开发知识之Java的异常处理
- 栈帧与操作数栈剖析及符号引用与直接引用的转换
- Redis管理各类型存储数据命令