Skip to content

Latest commit

 

History

History
282 lines (210 loc) · 6.67 KB

227-543551-[专业选修]约数_factors_函数的分分合合.sy.md

File metadata and controls

282 lines (210 loc) · 6.67 KB
show version enable_checker
step
1.0
true

嵌套调用

回忆

  • 上次我们了解到周易博大精深
  • 里面蕴含着很多古老的道理
  • 真的弄懂不容易
  • 善易者不卜
  • 自己去实践判断才有真实的收获
  • 比如模块化的道理
  • 一个模块一个功能
    • 高内聚
    • 低耦合
  • 模块化就都是优点么?
  • 就没有什么模块化导致的问题么?🤔

约数

  • Dividend ÷ Divisor = Quotient
  • 被除数 ÷ 除数 = 商
    • 15 ÷ 3 = 5
    • 16 ÷ 2 = 8
    • 36 ÷ 4 = 9
    • 37 ÷ 4 = 9 ... 1

图片描述

  • 如果过被除数除以除数
    • 得到一个商
    • 并且余数为0
    • 就是被除数可以被除数整除
  • 此时
    • 除数就是被除数的
      • 因子
      • 约数
      • factor
  • 如果我想要计算所有质因数

分步走

图片描述

  • 一步一步来
  • 就像造汽车一样
  • 先造各种零部件

各种部件

  • 轮胎厂(车间)生产轮胎

图片描述

  • 发动机厂(车间)生产发动机

图片描述

  • 最终组装到一起

组装

  • 通过板材焊接车身

图片描述

  • 最后整装

图片描述

  • 一步一步来
  • 这就是工业化的思路
  • 各个功能(functional)模块相对独立
    • 高内聚低耦合
  • 具体轮胎厂工艺改良了
    • 总装这里不用管
    • 那是人家轮胎厂内部的事情
    • 总装只要拿到轮子就ok了
  • 厂(车间)之间原来内在联系被分割
  • 工厂这个词怎么来的?

工厂

  • 工厂(factory)
    • 一个工业化(industrial)的设施(facility)
    • 里面有很多机器
    • 工人操作机器完成一些流程
  • 最开始工厂只是配置了一台珍妮纺纱机(spinning-jenny)的家庭作坊
    • jenny也是engine的缩写
    • 引擎带动工业自动化不断加速和扩大规模

图片描述

  • 人类也就从农业时代进入到了工业时代

工业

  • 本来人们的主要工作是农业
    • 翻土、用脚底板(plat)把植物(plant)种子埋到土壤里面
    • 所以plant也指埋在对方里面的卧底
    • 然后就收获植物(plant)作为粮食

图片描述

  • 后来人们把机器种植(plant)到地上
    • 产生了工厂厂房(plant)
    • 源源不断地像农场一样产出各种产品

图片描述

  • 大工厂随着工业革命而发展
    • 资金量和用地越来越大
    • 逐渐替代了家庭手工业的小作坊

大工厂与因子

  • facility
    • 前面的词根fac-表示“做”
    • 表示“易于,善于”
    • 字面意思就是“易于做事,善于做事”
    • 后被用作具体名词,表示能够带来便利,使做事变得更加容易的设备或设施

图片描述

  • factor是
    • 做事的人
    • 发挥作用的事物
    • 因素、要素、因子

图片描述

  • factory
    • 用来做事的场所

约数集合

图片描述

  • 这样我们得到一个约数的集合
  • 然后再对约数的集合进行下一步操作
  • 下一个函数就是判断某数字是否是质数

图片描述

质数(prime)

  • 质数是指在大于1的自然数中
    • 除了1和它本身以外不再有其他因数的自然数

图片描述

  • 质数(prime)是主要的
  • 非质数是合成(Composite)数

图片描述

  • 我们要找出因数中所有的质数(prime)
  • 也就是要找质(prime)因数(factors)的集合(set)

代码

  • 这确实可以实现
def get_factor_set(num):
    s = set()
    for i in range(2, num + 1):
        if num % i == 0:
            s.add(i)
    return s

def is_prime(num):
    for i in range(2,int(num / 2) + 1):
        if num % i == 0:
            return False
    return True

def get_prime_factor_set(num):
    s = set()
    for i in get_factor_set(num):
        if is_prime(i):
            s.add(i)
    return s


print(get_prime_factor_set(36))
  • 当num=2时
    • range(2,int(num / 2) + 1) 为 range(2,2)
    • 循环被跳过
    • 返回True
  • 当num=3时
    • range(2,int(num / 2) + 1) 为 range(2,2)
    • 循环被跳过
    • 返回True
  • 当num=4时
    • range(2,int(num / 2) + 1) 为 range(2,3)
    • 循环可进入
    • num%2 == 0成立
    • 有约数
    • 返回False
  • 而且是层层嵌套
    • 完成的求质因数集合的方式
  • 但是这个效率真的高么?

新的模块

  • 感觉这一个函数就能解决问题啊
  • 有必要调来调去的么?
def get_prime_factor_set(num):
    s = set()
    for i in range(2, num + 1):
        if num % i == 0:
            flag = True
            for j in range(2, int(i / 2) + 1):
                if i % j == 0:
                    flag = False
                    break
            if flag == True:
                s.add(i)
    return s

print(get_prime_factor_set(36))
  • 我们先看看实际的时长

测时

import timeit

with open("factor.py") as f:
    code = f.read()
    d1 = timeit.timeit(code,number=100)
print(d1)

with open("factor2.py") as f:
    code = f.read()
    d2 = timeit.timeit(code,number=100)
print(d2)
  • 测试结果如何呢?

结果

  • 实际验证结果说明
    • 这个通过函数嵌套调用的方式
    • 开销并不大

图片描述

  • 和想象中不符
  • 但是事实就是事实!!!
  • 这种优化区别不大

总结

  • 我们这次比较了两种做法
    • 两个函数
      • 先求因数集合
      • 再判断是否是质数
    • 一个函数
      • 求解出所有质因数
  • 两种做法
    • 从算法上来说区别不大
    • 运行的结果是时间区别不大
  • 实践证明函数调用的开销其实不大
    • 功能最好拆分成高内聚、低耦合的函数
  • 但是这个算法还可以优化么?🤔
  • 我们下次再说👋