问题描述:从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种方法生成不重复数字整数相关推荐

  1. 递归和循环两种方法完成树的镜像转换

    /* copyright@nciaebupt 转载出处:http://blog.csdn.net/nciaebupt/article/details/8506038 题目:输入一颗二元查找树,将该树转 ...

  2. 《 Python List列表全实例详解系列(四)》__列表删除元素(4种方法)删除重复元素(去重)(8种方法)

    <  Python List列表全实例详解系列(四)> __列表删除元素(4种方法)删除重复元素(去重)(8种方法) 我的技术成长&学习资料整理分享之路 我遇到问题查找资料时,经常 ...

  3. Excel如何快速生成不重复随机整数

    日常工作中我们经常会遇到要生成随机数的情况,比如分考场.分班级.抽样.抽奖等等.下面就给大家介绍一下如何生成不重复随机数. 一.工具法 1.如下图是某学校考试座次表,姓名列已经完成,现在我们要在座次列 ...

  4. php创建不重复的7位数字,php如何生成不重复数字

    php生成不重复数字的方法是:可以通过mt_rand()函数来实现.函数语法:[mt_rand(min,max)],例如[mt_rand(10,100)],表示生成一个介于10和100之间(包括10和 ...

  5. VBA实现两种方法生成任意概率分布的随机数

    引子 一把武器的品质有分为最下级.下级.中级.上级.最上级五档,我希望在击杀一只怪物的时候,这把武器的掉率:最下级>下级>中级>上级>最上级,问如何设计满足上面的需求? 在游戏 ...

  6. mysql 随机取不重复数据_随机生成不重复数字,想做Excel抽奖器你必须掌握!

    年会期间,大家最期待的便是抽奖环节了,只是有人欢喜有人忧,有的人连续几年每次都能抽中,有的人就像我一样,年年不中.... 人人概率相等,我觉得是不存在的 那如何用Excel做一个简易抽奖器呢?这个你必 ...

  7. C++ 随机数生成的2种方法--生成指定范围内的随机数

    第一种是传统的方法: #include <iostream>using namespace std;int main() {srand(NULL);for (int i = 0; i &l ...

  8. 三种方法生成随机数之srand篇

    srand()函数:随机数发生器的初始化函数,需要提供一个种子,这个种子会对应一个随机数.如果使用相同的种子,rand() 函数会出现一样的随机数.默认种子数是1,即srand(1). srand() ...

  9. treeview递归绑定的两种方法

    方法一: public void creattree(int fid, TreeNode parentnode){DataTable dt = new DataTable();dt = op.Bind ...

最新文章

  1. 阿里云API网关(8)开发指南-SDK下载
  2. python中文乱码例子
  3. 使用LeakCanary遇到的问题 就是不弹出来
  4. 机器人学习--Imperial College London机器人学课程
  5. SAP Spartacus 里的 .release-it.json 文件
  6. 前端攻略系列(二) - 前端各种面试题
  7. 手把手教你入门Git --- Git使用指南(Linux)
  8. python中set函数是什么数据类型_Python基本数据类型之set
  9. 一文带你了解GaussDB(DWS) 的Roach逻辑备份实现原理
  10. 启用sharepoin2013中的ChartWebPart
  11. python循环语句输出_python循环语句
  12. python cad 二次开发bom_python处理BOM
  13. python全栈开发工程师_老男孩Python高级全栈开发工程师三期完整无加密带课件(共104天)...
  14. TensorFlow之saved_model使用笔记
  15. [电动智能汽车-3]:原理 - 整车控制器VCU功能
  16. 绘制一幅蓝图_给未来画一幅蓝图
  17. 《c语言程序设计》第一次网上作业,精编国家开放大学电大《C语言程序设计》《劳动与社会保障法》网络课形考网考作业(合集)答案...
  18. 组合数学 多重集的排列和组合
  19. C语言----小游戏
  20. 2018技术胖Web前端视频教程全套

热门文章

  1. mysql shell无法启动服务_[shell脚本] mysql服务启动脚本
  2. Java 虚拟机学习笔记 | 运行时数据区总结
  3. ReactNative绑定函数中的this
  4. java swing mysql实现的员工工资管理系统项目
  5. 基于JAVA+SpringMVC+Mybatis+MYSQL的养老社区管理系统
  6. 【JVM】Java虚拟机
  7. POJ-2456.Aggressivecows.(二分求解最大化最小值)
  8. Java开发知识之Java的异常处理
  9. 栈帧与操作数栈剖析及符号引用与直接引用的转换
  10. Redis管理各类型存储数据命令