
本文介绍一种贪心算法,用于高效合并带格式的文本片段并生成最简化的嵌套html结构,通过智能排序开启标签的顺序(按覆盖长度降序),最小化总标签数量。
本文介绍一种贪心算法,用于高效合并带格式的文本片段并生成最简化的嵌套html结构,通过智能排序开启标签的顺序(按覆盖长度降序),最小化总标签数量。
在将多个带样式标记的文本(如 text1[bold,italic])拼接为语义清晰、嵌套最优的 HTML 时,核心挑战在于:避免冗余标签嵌套,同时最大化共用外层样式范围。例如,text1[bold,italic] + text2[bold] + text3[] 不应渲染为 text1text2text3(6 个标签),而应合并为 text1text2text3(4 个标签);更进一步,当 italic 覆盖更长连续段时(如 text1[bold,italic] + text2[italic] + text3[]),应让 成为最外层容器:text1text2text3。
✅ 算法原理:贪心 + 覆盖长度优先
该问题本质是「区间格式对齐」——每个文本片段对应一个位置区间 [i, i+1) 和一组激活样式。最优解的关键洞察是:
-
关闭样式:在格式切换点(如从
bold,italic切换到bold),需关闭所有不再需要的样式(即italic),且必须按栈式逆序闭合(先关内层,再关外层); - 开启样式:需新增的样式,应按其后续连续覆盖长度降序排列开启——覆盖越长的样式越靠外,从而减少嵌套层数与总标签数。
✅ 该贪心策略已被证明在最小化总开始/结束标签数目标下是最优的(类似“括号最小嵌套”问题,可归纳证明)。
DeepBI DHTML 页面生成器下载生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
? 实现步骤(Python 风格伪代码)
def format_to_html(texts: List[Tuple[str, List[str]]]) -> str:
# texts[i] = (content, [style1, style2, ...]), e.g. ("text1", ["bold", "italic"])
if not texts:
return ""
# Step 1: Precompute coverage length for each style at each position
n = len(texts)
# style_span[style] = longest consecutive suffix starting at i where style is active
style_span = defaultdict(lambda: [0] * n)
for style in set(style for _, styles in texts for style in styles):
# backward pass: compute max trailing length where `style` is present
length = 0
for i in range(n - 1, -1, -1):
if style in texts[i][1]:
length += 1
else:
length = 0
style_span[style][i] = length
# Step 2: Simulate tag stack & build output
html_parts = []
open_stack = [] # list of (style, span_length), ordered by opening sequence
current_styles = set()
for i, (content, styles) in enumerate(texts):
# 1. Close styles no longer needed (set difference: current \ styles)
to_close = current_styles - set(styles)
while open_stack and open_stack[-1][0] in to_close:
_, _ = open_stack.pop()
html_parts.append(f"{style_to_tag(open_stack[-1][0])}>")
current_styles.discard(open_stack[-1][0])
# 2. Open newly needed styles — sorted by coverage length DESC
to_open = set(styles) - current_styles
# Sort by style_span[style][i], descending
sorted_open = sorted(to_open, key=lambda s: style_span[s][i], reverse=True)
for style in sorted_open:
tag = style_to_tag(style)
html_parts.append(f"")
open_stack.append((style, style_span[style][i]))
current_styles.add(style)
# Append content (no escaping for brevity; add html.escape() in production)
html_parts.append(content)
# Close all remaining open tags (LIFO order)
while open_stack:
style, _ = open_stack.pop()
html_parts.append(f"{style_to_tag(style)}>")
return "".join(html_parts)
def style_to_tag(style: str) -> str:
return {"bold": "b", "italic": "i", "underline": "u"}.get(style, style)
? 示例验证
输入:
texts = [
("text1", ["bold", "italic"]),
("text2", ["italic"]),
("text3", [])
]
-
italic覆盖长度:[3, 2, 0]→ 在位置 0 最长(3),优先开启 -
bold覆盖长度:[1, 0, 0]→ 仅位置 0 有效
→ 输出:text1text2text3✅
⚠️ 注意事项
-
样式命名需唯一且映射明确:建议统一风格(如
bold→),避免歧义; -
需转义内容:生产环境务必对
content调用html.escape()防 XSS; -
空格与换行:上述算法输出紧凑 HTML;如需可读性缩进,可在
html_parts拼接时插入\n和缩进逻辑; - 性能:时间复杂度 O(n·m),其中 n 是文本数,m 是样式种类数,适用于常规文档规模(万级以内)。
通过该算法,你不仅能精准控制 HTML 嵌套层级,还能显著减少冗余标签,提升渲染效率与可维护性——真正实现「语义正确」与「结构精简」的统一。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











