寻找矩形内3种不同组件的所有布局组合的算法方案
3组件矩形布局全枚举实现方案
一、先明确布局等价规则
组件尺寸不影响布局判定,核心看组件间的拓扑关系(并列、嵌套的结构逻辑),比如横向三并列和纵向三并列视为同一种布局,只要结构逻辑一致就算同一类。
二、枚举所有拓扑布局类型
3个组件在矩形内的拓扑结构总共4种(符合你描述的“1-2号相同,其余三种不同”的设定):
- 类型1:三组件线性并列(所有组件在同一层级,无嵌套)
- 类型2:单组件独立区域 + 另外两组件并列在另一区域
- 类型3:两组件嵌套 + 第三组件与外层组件并列
- 类型4:三组件层层嵌套(A包含B,B包含C)
三、代码落地思路
1. 抽象布局结构
用嵌套对象表示布局的拓扑逻辑,忽略尺寸和具体方向:
// 枚举所有布局结构 const allLayouts = [ { id: 1, name: "线性并列型", structure: { type: "parallel", count: 3 } }, { id: 2, name: "单区双并列型", structure: { type: "container", children: [{ type: "parallel", count: 2 }, { type: "component" }] } }, { id: 3, name: "嵌套并列型", structure: { type: "container", children: [{ type: "nested", count: 2 }, { type: "component" }] } }, { id: 4, name: "三层嵌套型", structure: { type: "nested", count: 3 } } ];
2. 布局等价性判定
如果需要判断两个布局是否属于同一类,递归比较拓扑结构即可:
function isSameLayout(a, b) { if (a.type !== b.type) return false; // 线性并列/嵌套只看数量 if (["parallel", "nested"].includes(a.type)) { return a.count === b.count; } // 容器类型:排序后递归比较子结构(忽略子项顺序) if (a.type === "container") { const sortChildren = arr => [...arr].sort((x, y) => JSON.stringify(x).localeCompare(JSON.stringify(y))); const sortedA = sortChildren(a.children); const sortedB = sortChildren(b.children); return sortedA.every((child, idx) => isSameLayout(child, sortedB[idx])); } // 基础组件直接判定相同 return true; }
3. 可视化渲染(可选)
如果需要把抽象结构转为可视化界面,递归遍历结构生成DOM:
function renderLayout(layout) { const el = document.createElement("div"); el.style.border = "1px solid #ccc"; el.style.boxSizing = "border-box"; if (layout.type === "component") { el.style.flex = 1; el.style.display = "flex"; el.style.alignItems = "center"; el.style.justifyContent = "center"; el.textContent = "组件"; return el; } if (layout.type === "parallel") { el.style.display = "flex"; for (let i = 0; i < layout.count; i++) { el.appendChild(renderLayout({ type: "component" })); } } if (layout.type === "nested") { el.style.display = "flex"; el.style.flex = 1; let current = el; for (let i = 0; i < layout.count; i++) { const child = renderLayout(i === layout.count - 1 ? { type: "component" } : { type: "nested", count: 1 }); current.appendChild(child); current = child; } } if (layout.type === "container") { el.style.display = "flex"; layout.children.forEach(child => el.appendChild(renderLayout(child))); } return el; } // 示例:渲染第一个布局到页面 document.body.appendChild(renderLayout(allLayouts[0].structure));
四、核心注意事项
- 所有逻辑围绕拓扑结构展开,完全忽略组件尺寸、具体排列方向(如果横向/纵向结构一致视为同类)
- 3组件的拓扑结构只有4种,枚举时直接覆盖即可,无需复杂的动态生成
内容的提问来源于stack exchange,提问作者CodeTiger
相关产品推荐
相关产品推荐

