如何实现两个有序数组的GitHub风格差异对比?
实现双有序数组的GitHub风格对比输出
需求说明
现有两个按字母顺序排序、元素唯一的数组,部分元素重复,需要输出类似文件对比的双列列表:对应位置元素相同则两边都显示,某一边没有对应元素则显示空白。
示例数组
$src = ["apple", "cherry", "grape", "lemon", "orange", "strawberry"]; $dst = ["apple", "banana", "cherry", "orange", "pear"];
期望输出
1.apple 1.apple 2. 2.banana 3.cherry 3.cherry 4.grape 4. 5.lemon 5. 6.orange 6.orange 7. 7.pear 8.strawberry 8.
现有代码雏形
<ul> <?php foreach($src as $src_item) : ?> <li><?php echo $src_item; // what else??? ?></li> <?php endforeach; ?> </ul>
可行实现方法
因为两个数组都是有序的,用双指针法效率最高,无需嵌套循环。核心逻辑是同时遍历两个数组,对比当前指针指向的元素,决定两边的输出内容,再移动对应指针,直到两个数组都遍历完成。
完整实现代码:
<?php $src = ["apple", "cherry", "grape", "lemon", "orange", "strawberry"]; $dst = ["apple", "banana", "cherry", "orange", "pear"]; $i = 0; // src数组遍历指针 $j = 0; // dst数组遍历指针 $lineNum = 0; // 行号计数器 // 只要有一个数组未遍历完就继续循环 while ($i < count($src) || $j < count($dst)) { $lineNum++; $srcContent = ''; $dstContent = ''; // 对比当前元素,决定输出内容与指针移动 if ($i < count($src) && $j < count($dst)) { $compareResult = strcmp($src[$i], $dst[$j]); if ($compareResult === 0) { // 元素相同,两边都显示,同时移动两个指针 $srcContent = $src[$i]; $dstContent = $dst[$j]; $i++; $j++; } elseif ($compareResult < 0) { // src元素更小,仅显示src,移动src指针 $srcContent = $src[$i]; $i++; } else { // dst元素更小,仅显示dst,移动dst指针 $dstContent = $dst[$j]; $j++; } } elseif ($i < count($src)) { // src还有剩余元素,仅显示src $srcContent = $src[$i]; $i++; } else { // dst还有剩余元素,仅显示dst $dstContent = $dst[$j]; $j++; } // 格式化输出,用str_pad保证列对齐 $leftLine = $lineNum . '.' . $srcContent; $rightLine = $lineNum . '.' . $dstContent; echo str_pad($leftLine, 15) . $rightLine . "\n"; } ?>
代码解释
- 双指针
$i和$j分别跟踪两个数组的当前遍历位置,$lineNum记录当前行号。 - 循环处理三种场景:
- 两个指针都未越界:对比元素,相同则同时移动指针;否则移动元素更小的一侧指针。
- 仅
$src有剩余元素:依次输出剩余内容,直到$src遍历完成。 - 仅
$dst有剩余元素:依次输出剩余内容,直到$dst遍历完成。
- 用
str_pad格式化每行内容,确保两列对齐,输出格式符合要求。
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

