
本文介绍一种高效算法,将字符串数组两两配对,使其长度之和尽可能接近目标值 $limit,并确保每个元素仅被使用一次,最终生成最优分组结果。
本文介绍一种高效算法,将字符串数组两两配对,使其长度之和尽可能接近目标值 $limit,并确保每个元素仅被使用一次,最终生成最优分组结果。
在实际开发中,我们常需对字符串列表进行“智能打包”——例如生成标签云、拼接多字段显示文本、或优化 UI 中的行内内容布局。核心诉求是:将数组中的字符串两两组合,使每组总长度最接近给定阈值(如 29),且每个字符串最多参与一次组合,剩余未匹配项单独成组。 这本质上是一个受限的“近似二维装箱”问题,但因规模较小(通常
✅ 解决思路
-
穷举所有两两组合(排除自身重复),计算其与
$limit的绝对差值|len(a) + len(b) - $limit|; - 按差值升序排序:差值越小,表示该组合越贴近目标长度;
- 贪心选取:遍历排序后的组合列表,仅当两个字符串均未被使用时,才采纳该组合,并标记为已占用;
- 补全未匹配项:最后扫描原数组,将所有未出现在任何组合中的字符串作为独立项加入结果。
? 完整实现代码
<?php $limit = 29;
$arr = [
'Isofix',
'Parkinghelp',
'Rainsensor',
'Led light',
'Hill Start Assist',
'Dynamic brake light',
'Cornering Brake Control'
];
// 步骤1:生成所有不重复两两组合及其与 $limit 的距离
$candidates = [];
$n = count($arr);
for ($i = 0; $i < $n; $i++) {
for ($j = $i + 1; $j < $n; $j++) {
$totalLen = strlen($arr[$i]) + strlen($arr[$j]);
$distance = abs($totalLen - $limit);
$candidates[] = [
'dist' => $distance,
'a' => $arr[$i],
'b' => $arr[$j]
];
}
}
// 步骤2:按距离升序排序(最接近者优先)
usort($candidates, function($x, $y) {
return $x['dist'] $y['dist'];
});
// 步骤3:贪心选择互斥组合
$used = [];
$result = [];
foreach ($candidates as $pair) {
$a = $pair['a'];
$b = $pair['b'];
if (!in_array($a, $used) && !in_array($b, $used)) {
$result[] = $a . ' * ' . $b;
$used[] = $a;
$used[] = $b;
}
}
// 步骤4:添加所有未被使用的原始元素
foreach ($arr as $item) {
if (!in_array($item, $used)) {
$result[] = $item;
}
}
// 输出最终分组(保持逻辑清晰,可直接用于前端展示)
print_r($result);
?>
? 输出示例
Array
(
[0] => Isofix * Cornering Brake Control
[1] => Rainsensor * Dynamic brake light
[2] => Parkinghelp * Hill Start Assist
[3] => Led light
)
✅ 完全匹配预期:前三组长度分别为 6+23=29、10+19=29、11+17=28;Led light(9 字符)因无合适配对而独立成项。
⚠️ 注意事项与优化建议
-
时间复杂度:当前实现为 O(n³),适用于 n ≤ 200 的场景;若数据量更大,建议改用哈希表记录已用索引(而非
in_array),将查找降至 O(1); - 扩展性:本方案默认仅支持两两组合。如需支持三元组或动态组大小,应改用回溯或动态规划(但复杂度显著上升);
-
空格与格式处理:
strlen()计算含空格长度,若需忽略前后空格,建议预处理:trim($str); -
稳定性:当多个组合距离相同时(如都差 0),
usort不保证原始顺序,如需确定性结果,可在排序回调中追加次级键(如[$x['a'], $x['b']] [$y['a'], $y['b']])。
该方法兼顾准确性与可读性,是 PHP 中解决“字符串长度最优配对分组”问题的实用范式。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











