当前位置: 首页 > news >正文

【算法教程】排列与组合的实现

数据准备

  • 在讲排列与组合之前,我们先定义数据元素类型Fruit
class Fruit{
    constructor(name,price){
        this.name = name
        this.price = price
    }
}

排列

  • 对N个不同元素进行排序,总共有多少不同的排列方式?
Step1: 从N个元素中取1个,共N种取法
Step2: 从剩下N-1个元素取1个,共N-1种
......
StepN: 从剩1个元素中取1个,共1种
所以共有 A=N*(N-1)....*1 =N!
  • 例子:某水果店有以下水果,请对所有水果进行全排列,请输出所有排列
let fruits = [
    new Fruit('apple',5.3),
    new Fruit('banana',3.2),
    new Fruit('orange',4.6),
    new Fruit('watermelon',2.5)
]
  • 排列算法的javascript实现模板(DSF,最优解in-place)
const premutation = (elements)=>{
    let res = []
    const swap = (arr,i1,i2)=> [arr[i1],arr[i2]] = [arr[i2],arr[i1]]
    const dsf = (elements,k = 0)=>{
        let len = elements.length
        if(k == len-1){ // 如果想从N=4中,取3个的全排 只需要改这个k=3
            res.push([...elements.slice(0,k+1)])
            return
        }
        for(let i = k; i < len - 1 ; i++){
            swap(elements, i, k) // 从剩下[k,...,(len-2)]中 取一个 放到当前k位置
            dsf(elements, k + 1) // dsf继续下一个位置 [k+1,...,(len-2)]
            swap(elements,i , k) // 为下一个迭代(k+1)做回滚
        }
    }
    dsf(elements)
    return res
}
let premutations = premutation(fruits)
premutations.forEach((e,i)=>console.log(i,...e.map(x=>x.name)))

  • 测试结果
0 'apple' 'banana' 'orange' 'watermelon'
1 'apple' 'orange' 'banana' 'watermelon'
2 'banana' 'apple' 'orange' 'watermelon'
3 'banana' 'orange' 'apple' 'watermelon'
4 'orange' 'banana' 'apple' 'watermelon'
5 'orange' 'apple' 'banana' 'watermelon'

组合

  • 对N个不同元素进行排序,总共有多少不同的组合方式?
N个元素中,每个元素要么被放到某个组合中,或者不放,2种选择
所以共有 C=2^N

算法实现: 同样我们可以用DSF,但是还有更优解法-- 整型编码/bitmap
2^N种情况可以用N个bit来表示,通过实现对数组索引index来编码
  • 同样的例子:请输出所有组合
let fruits = [
    new Fruit('apple',5.3),
    new Fruit('banana',3.2),
    new Fruit('orange',4.6),
    new Fruit('watermelon',2.5)
]
  • 组合算法的javascript实现模板(bitmap)
const combination = (elements)=>{
    let res = []
    let len = elements.length
    let counts = 1 << len
    for(let bitmap = 0 ; bitmap < counts; bitmap++){
        let set = []
        for(let i=0 ; i < len ; i++){
            if((1<<i)&bitmap){ //对应位为1,怎加入当前集合种
                set.push(i)
            }
        }
        // set 只是数组索引的组合,需要转成对应element
        res.push(set.map(i=>elements[i])) // 完成一个集合的收集
    }
    return res
}
let combinations  = combination(fruits)
combinations.forEach((e,i)=>console.log(i,...e.map(x=>x.name)))
  • 测试结果
0 ''
1 'apple'
2 'banana'
3 'apple' 'banana'
4 'orange'
5 'apple' 'orange'
6 'banana' 'orange'
7 'apple' 'banana' 'orange'
8 'watermelon'
9 'apple' 'watermelon'
10 'banana' 'watermelon'
11 'apple' 'banana' 'watermelon'
12 'orange' 'watermelon'
13 'apple' 'orange' 'watermelon'
14 'banana' 'orange' 'watermelon'
15 'apple' 'banana' 'orange' 'watermelon'

相关文章:

  • 华为OD 绘图机器(100分)【java】A卷+B卷
  • 项目经理之识别项目干系人
  • 百分点科技受邀参加“一带一路”国际合作高峰论坛
  • Android 特权应用 privapp-permissions 权限解读
  • 华为数通方向HCIP-DataCom H12-831题库(多选题:1-20)
  • Ansible 的脚本 --- playbook 剧本
  • SSD算法学习(单步多框目标检测)
  • 美格智能出席无锡智能网联汽车生态大会,共话数字座舱新势力
  • 【数据结构】模拟实现无头单向非循环链表
  • JOSEF约瑟 JHOK-ZBM1;JHOK-ZBL1多档切换式漏电(剩余)继电器 面板导轨安装
  • Flink之常用处理函数
  • 使用cxf将wsdl文件转换成java文件 webservice
  • 中文编程开发语言工具开发的实际软件案例:称重管理系统软件
  • 2023年最新版CorelDraw(cdr)软件下载安装教程
  • 【广州华锐互动】VR营销心理学情景模拟培训系统介绍
  • Mysql数据库表操作--存储
  • 数据结构与算法(十):动态规划与贪心算法
  • 如何借助边缘智能网关打造智慧城市便民驿站
  • Linux性能优化--性能工具:下一步是什么
  • CAdUiPaletteSet创建后乱码 2023/10/17 下午11:25:07
  • 美国第一季度经济环比萎缩0.3%,特朗普:怪拜登,与关税无关
  • 马上评|启动最高层级医政调查,维护医学一方净土
  • 国台办:民进党当局所谓“对等尊严”,就是企图改变两岸同属一中
  • 全国人民代表大会常务委员会公告〔十四届〕第十号
  • 百年传承,再启新程,参天中国迎来2.0时代
  • 解放日报:这是一场需要定力和实力的“科技长征”