Vâng, xem xét rằng bạn có thể sử dụng XOR
trong tình huống này để tìm các phần chung của chuỗi. Bất kỳ lúc nào bạn x hoặc hai byte giống nhau, bạn sẽ nhận được nullbyte làm đầu ra. Vì vậy, chúng tôi có thể sử dụng điều đó để làm lợi thế của mình:
$first = $array[0];
$length = strlen($first);
$count = count($array);
for ($i = 1; $i < $count; $i++) {
$length = min($length, strspn($array[$i] ^ $first, chr(0)));
}
Sau vòng lặp đơn đó, $length
biến sẽ bằng giá trị cơ bản chung dài nhất giữa mảng các chuỗi. Sau đó, chúng ta có thể trích xuất phần chung từ phần tử đầu tiên:
$common = substr($array[0], 0, $length);
Và bạn có nó rồi đấy! Như một chức năng:
function commonPrefix(array $strings) {
$first = $strings[0];
$length = strlen($first);
$count = count($strings);
for ($i = 1; $i < $count; $i++) {
$length = min($length, strspn($strings[$i] ^ $first, chr(0)));
}
return substr($first, 0, $length);
}
Lưu ý rằng nó sử dụng nhiều hơn một lần lặp, nhưng những lần lặp đó được thực hiện trong thư viện, vì vậy trong các ngôn ngữ thông dịch, điều này sẽ mang lại hiệu quả rất lớn ...
Bây giờ, nếu bạn chỉ muốn các đường dẫn đầy đủ, chúng ta cần cắt bớt đến /
ký tự cuối cùng . Vì thế:
$prefix = preg_replace('#/[^/]*$', '', commonPrefix($paths));
Bây giờ, nó có thể cắt quá mức hai chuỗi chẳng hạn như /foo/bar
và /foo/bar/baz
sẽ bị cắt /foo
. Nhưng ngắn thêm một vòng lặp để xác định xem các ký tự tiếp theo là một trong hai /
hoặc end-of-string, tôi không thể nhìn thấy một con đường xung quanh đó ...