#摘要#
一转眼过去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符号上的数字。找到这一层的节点后,按照自己的路径上找,即可形成一个解。我这里代码的逻辑完全来源于手动演算的结果。
经简单测试,没有发现问题。期待能有更多数学问题,能用这种方式解决,下次再见!