Typescript算法研究之【排列组合】

#摘要#

一转眼过去6年多了,没有更新过博客,由于近期遇到了用代码解决数学上的问题,比如今天说的排列组合。网上查了下,有好多人都实现了,方法各异,但都没有按照面向对象的方式求解。我承认我今天写的这些,可能小题大作,但我是按照最简单逻辑思维方式拓展开的,容易理解。

我们都知道排列和组合的区别,一个有顺序,一个没顺序。所以我用一个【全部的树】来表示排列结果,用一个【向后的树】来表示组合结果。看代码,您就知道了。

class PCNode {
  value = 0
  index = 0
  parent: PCNode | null = null
  children: Array<PCNode>
  level = 1

  constructor() {
    this.children = new Array<PCNode>()
  }

  get pathIndexList(): Array<number> {
    const arr = new Array<number>()
    arr.push(this.index)
    if (this.parent) {
      let parent: PCNode | null = this.parent
      while (parent) {
        arr.push(parent.index)
        parent = parent.parent
      }
    }
    return arr
  }

  get pathValueList(): Array<number> {
    const arr = new Array<number>()
    arr.push(this.value)
    if (this.parent) {
      let parent: PCNode | null = this.parent
      while (parent) {
        arr.push(parent.value)
        parent = parent.parent
      }
    }
    return arr
  }
}
class PermutationCombination {
  nodeInfo: Array<PCNode>
  originArr: Array<number>

  constructor(isPermutation: boolean, originArray: Array<number>) {
    this.nodeInfo = new Array<PCNode>()
    this.originArr = originArray
    isPermutation ? this.initPermutation() : this.initCombination()
  }

  private initPermutation() {
    const generateChildren = (parent: PCNode) => {
      for (let index = 0; index < this.originArr.length; index++) {
        if (parent.pathIndexList.indexOf(index) === -1) {
          const child = new PCNode()
          child.level = parent.level + 1
          child.index = index
          child.value = this.originArr[index]
          child.parent = parent
          parent.children.push(child)
          generateChildren(child)
        }
      }
    }

    for (let index = 0; index < this.originArr.length; index++) {
      const root = new PCNode()
      root.value = this.originArr[index]
      root.index = index
      this.nodeInfo.push(root)
      generateChildren(root)
    }
  }

  private initCombination() {
    const generateChildren = (parent: PCNode, startIndex: number) => {
      for (let index = startIndex; index < this.originArr.length; index++) {
        const child = new PCNode()
        child.level = parent.level + 1
        child.value = this.originArr[index]
        child.parent = parent
        parent.children.push(child)
        generateChildren(child, index + 1)
      }
    }

    for (let index = 0; index < this.originArr.length; index++) {
      const root = new PCNode()
      root.value = this.originArr[index]
      root.index = index
      this.nodeInfo.push(root)
      generateChildren(root, index + 1)
    }
  }

  getResultByDeep(deep: number) {
    const allConditions = new Array<Array<number>>()
    console.log(this.nodeInfo)
    const getChildByDeep = (parent: PCNode) => {
       if (parent.level === deep) {
         allConditions.push(parent.pathValueList)
       } else if (parent.level < deep) {
         parent.children.forEach(child => getChildByDeep(child))
       }
    }
    this.nodeInfo.forEach((value: PCNode) => getChildByDeep(value))
    return allConditions
  }
}

使用方法:
 

const pc = new PermutationCombination(false, [1,2,3,2,3])
console.log(pc.getResultByDeep(3))

解释下,这里传的参数3,也就是节点中的level值,就是我们说的C53中的C符号上的数字。找到这一层的节点后,按照自己的路径上找,即可形成一个解。我这里代码的逻辑完全来源于手动演算的结果。
 

经简单测试,没有发现问题。期待能有更多数学问题,能用这种方式解决,下次再见!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值