Tetris-ing một mảng


99

Hãy xem xét mảng sau:

/www/htdocs/1/sites/lib/abcdedd
/www/htdocs/1/sites/conf/xyz
/www/htdocs/1/sites/conf/abc/def
/www/htdocs/1/sites/htdocs/xyz
/www/htdocs/1/sites/lib2/abcdedd

cách ngắn nhất và thanh lịch nhất để phát hiện đường cơ sở chung là gì - trong trường hợp này

/www/htdocs/1/sites/

và xóa nó khỏi tất cả các phần tử trong mảng?

lib/abcdedd
conf/xyz
conf/abc/def
htdocs/xyz
lib2/abcdedd

4
Điều này có thể đáng để thử: en.wikibooks.org/wiki/Algorithm_implementation/Strings/… (Tôi đã thử và nó hoạt động).
Richard Knop,

1
Rất tiếc! Rất nhiều đầu vào tuyệt vời. Tôi sẽ sử dụng một giải pháp để giải quyết vấn đề của mình, nhưng tôi cảm thấy rằng để thực sự chọn ra một câu trả lời hợp lý được chấp nhận, tôi sẽ phải so sánh các giải pháp. Có thể mất một lúc cho đến khi tôi làm được điều đó, nhưng tôi chắc chắn sẽ làm được.
Pekka,

tiêu đề giải trí: D btw: tại sao tôi không thể tìm thấy bạn trong danh sách người kiểm duyệt được đề cử? @Pekka
The Surrican,

2
không có câu trả lời được chấp nhận trong hai năm?
Gordon

1
@Pekka Bắt gần ba năm kể từ này không có câu trả lời được chấp nhận :( Và nó là một danh hiệu tuyệt vời như vậy mà tôi nhớ đến nó lúc nãy và googled "tetrising một mảng".
Camilo Martin

Câu trả lời:


35

Viết một hàm longest_common_prefixnhận hai chuỗi làm đầu vào. Sau đó, áp dụng nó cho các chuỗi theo bất kỳ thứ tự nào để giảm chúng về tiền tố chung của chúng. Vì nó là liên kết và giao hoán nên thứ tự không quan trọng đối với kết quả.

Điều này cũng giống như đối với các phép toán nhị phân khác, chẳng hạn như phép cộng hoặc ước số chung lớn nhất.


8
+1. Sau khi so sánh 2 chuỗi đầu tiên, sử dụng kết quả (đường dẫn chung) để so sánh với chuỗi thứ 3, v.v.
Milan Babuškov

23

Tải chúng vào cấu trúc dữ liệu trie. Bắt đầu từ nút cha, hãy xem nút nào có số con lớn hơn một. Khi bạn tìm thấy nút ma thuật đó, chỉ cần tháo cấu trúc nút cha và có nút hiện tại làm nút gốc.


10
Sẽ không phải hoạt động tải dữ liệu vào cấu trúc cây trie mà bạn mô tả kinda bao gồm thuật toán tìm tiền tố chung dài nhất, do đó làm cho việc sử dụng cấu trúc cây thực sự không cần thiết? Tức là tại sao phải kiểm tra cây cho nhiều con khi bạn có thể phát hiện ra điều đó trong khi xây dựng cây. Tại sao lại là một cái cây? Ý tôi là nếu bạn đã bắt đầu với một mảng. Nếu bạn có thể thay đổi bộ nhớ thành chỉ sử dụng trie thay vì mảng, tôi đoán nó có ý nghĩa.
Ben Schwehn

2
Tôi nghĩ rằng nếu bạn cẩn thận thì giải pháp của tôi sẽ hiệu quả hơn là xây dựng một bộ ba.
starblue,

Câu trả lời này là sai. Có những giải pháp tầm thường được đăng trong các câu trả lời của tôi và các câu trả lời khác là O (n).
Ari Ronen

@ el.pescado: Các truy vấn có kích thước tứ phân với độ dài của chuỗi nguồn trong trường hợp xấu nhất.
Billy ONeal

10
$common = PHP_INT_MAX;
foreach ($a as $item) {
        $common = min($common, str_common($a[0], $item, $common));
}

$result = array();
foreach ($a as $item) {
        $result[] = substr($item, $common);
}
print_r($result);

function str_common($a, $b, $max)
{
        $pos = 0;
        $last_slash = 0;
        $len = min(strlen($a), strlen($b), $max + 1);
        while ($pos < $len) {
                if ($a{$pos} != $b{$pos}) return $last_slash;
                if ($a{$pos} == '/') $last_slash = $pos;
                $pos++;
        }
        return $last_slash;
}

Đây là giải pháp tốt nhất được đăng cho đến nay, nhưng nó cần được cải thiện. Nó không tính đến đường dẫn chung dài nhất trước đó (có thể lặp lại nhiều chuỗi hơn mức cần thiết) và không tính đến đường dẫn (vì vậy /usr/lib/usr/lib2nó được /usr/libcoi là đường dẫn chung dài nhất, thay vì /usr/). Tôi (hy vọng) đã sửa cả hai.
Gabe

7

Vâng, xem xét rằng bạn có thể sử dụng XORtrong 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 đó, $lengthbiế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/foo/bar/bazsẽ 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 đó ...


3

Một cách tiếp cận ngây thơ sẽ là làm bùng nổ các đường dẫn /và so sánh liên tiếp mọi phần tử trong mảng. Vì vậy, ví dụ: phần tử đầu tiên sẽ trống trong tất cả các mảng, vì vậy nó sẽ bị loại bỏ, phần tử tiếp theo sẽ là www, nó giống nhau trong tất cả các mảng, vì vậy nó sẽ bị loại bỏ, v.v.

Cái gì đó như (chưa được kiểm tra)

$exploded_paths = array();

foreach($paths as $path) {
    $exploded_paths[] = explode('/', $path);
}

$equal = true;
$ref = &$exploded_paths[0]; // compare against the first path for simplicity

while($equal) {   
    foreach($exploded_paths as $path_parts) {
        if($path_parts[0] !== $ref[0]) {
            $equal = false;
            break;
        }
    }
    if($equal) {
        foreach($exploded_paths as &$path_parts) {
            array_shift($path_parts); // remove the first element
        }
    }
}

Sau đó, bạn chỉ cần giải mã các phần tử vào $exploded_pathslại:

function impl($arr) {
    return '/' . implode('/', $arr);
}
$paths = array_map('impl', $exploded_paths);

Điều đó cho tôi:

Array
(
    [0] => /lib/abcdedd
    [1] => /conf/xyz
    [2] => /conf/abc/def
    [3] => /htdocs/xyz
    [4] => /conf/xyz
)

Điều này có thể không mở rộng quy mô tốt;)


3

Được rồi, tôi không chắc cái này có chống đạn, nhưng tôi nghĩ nó hoạt động:

echo array_reduce($array, function($reducedValue, $arrayValue) {
    if($reducedValue === NULL) return $arrayValue;
    for($i = 0; $i < strlen($reducedValue); $i++) {
        if(!isset($arrayValue[$i]) || $arrayValue[$i] !== $reducedValue[$i]) {
            return substr($reducedValue, 0, $i);
        }
    }
    return $reducedValue;
});

Điều này sẽ lấy giá trị đầu tiên trong mảng làm chuỗi tham chiếu. Sau đó, nó sẽ lặp qua chuỗi tham chiếu và so sánh từng ký tự với ký tự của chuỗi thứ hai ở cùng một vị trí. Nếu một char không khớp, chuỗi tham chiếu sẽ được rút ngắn đến vị trí của char và chuỗi tiếp theo được so sánh. Khi đó hàm sẽ trả về chuỗi khớp ngắn nhất.

Hiệu suất phụ thuộc vào các chuỗi được đưa ra. Chuỗi tham chiếu càng sớm càng ngắn thì mã kết thúc càng nhanh. Tôi thực sự không biết làm thế nào để đưa nó vào một công thức.

Tôi thấy rằng cách tiếp cận của Artefacto để sắp xếp các chuỗi làm tăng hiệu suất. Thêm

asort($array);
$array = array(array_shift($array), array_pop($array));

trước khi array_reduceý chí tăng đáng kể hiệu suất.

Cũng lưu ý rằng điều này sẽ trả về chuỗi con ban đầu phù hợp dài nhất , chuỗi này linh hoạt hơn nhưng sẽ không cung cấp cho bạn đường dẫn chung . Bạn phải chạy

substr($result, 0, strrpos($result, '/'));

về kết quả. Và sau đó bạn có thể sử dụng kết quả để loại bỏ các giá trị

print_r(array_map(function($v) use ($path){
    return str_replace($path, '', $v);
}, $array));

cái nào sẽ cho:

[0] => /lib/abcdedd
[1] => /conf/xyz/
[2] => /conf/abc/def
[3] => /htdocs/xyz
[4] => /lib2/abcdedd

Phản hồi hoan nghênh.


3

Bạn có thể xóa tiền tố theo cách nhanh nhất, chỉ đọc mỗi ký tự một lần:

function findLongestWord($lines, $delim = "/")
{
    $max = 0;
    $len = strlen($lines[0]); 

    // read first string once
    for($i = 0; $i < $len; $i++) {
        for($n = 1; $n < count($lines); $n++) {
            if($lines[0][$i] != $lines[$n][$i]) {
                // we've found a difference between current token
                // stop search:
                return $max;
            }
        }
        if($lines[0][$i] == $delim) {
            // we've found a complete token:
            $max = $i + 1;
        }
    }
    return $max;
}

$max = findLongestWord($lines);
// cut prefix of len "max"
for($n = 0; $n < count($lines); $n++) {
    $lines[$n] = substr(lines[$n], $max, $len);
}

Thật vậy, so sánh dựa trên ký tự sẽ là nhanh nhất. Tất cả các giải pháp khác sử dụng toán tử "đắt tiền" mà cuối cùng cũng sẽ thực hiện (nhiều) so sánh ký tự. Nó thậm chí còn được đề cập đến trong thánh thư Joel !
Jan Fabry

2

Điều này có lợi thế là không có độ phức tạp thời gian tuyến tính; tuy nhiên, đối với hầu hết các trường hợp, sắp xếp chắc chắn sẽ không phải là thao tác mất nhiều thời gian hơn.

Về cơ bản, phần thông minh (ít nhất là tôi không thể tìm ra lỗi với nó) ở đây là sau khi phân loại, bạn sẽ chỉ phải so sánh đường dẫn đầu tiên với đường dẫn cuối cùng.

sort($a);
$a = array_map(function ($el) { return explode("/", $el); }, $a);
$first = reset($a);
$last = end($a);
for ($eqdepth = 0; $first[$eqdepth] === $last[$eqdepth]; $eqdepth++) {}
array_walk($a,
    function (&$el) use ($eqdepth) {
        for ($i = 0; $i < $eqdepth; $i++) {
            array_shift($el);
        }
     });
$res = array_map(function ($el) { return implode("/", $el); }, $a);

2
$values = array('/www/htdocs/1/sites/lib/abcdedd',
                '/www/htdocs/1/sites/conf/xyz',
                '/www/htdocs/1/sites/conf/abc/def',
                '/www/htdocs/1/sites/htdocs/xyz',
                '/www/htdocs/1/sites/lib2/abcdedd'
);


function splitArrayValues($r) {
    return explode('/',$r);
}

function stripCommon($values) {
    $testValues = array_map('splitArrayValues',$values);

    $i = 0;
    foreach($testValues[0] as $key => $value) {
        foreach($testValues as $arraySetValues) {
            if ($arraySetValues[$key] != $value) break 2;
        }
        $i++;
    }

    $returnArray = array();
    foreach($testValues as $value) {
        $returnArray[] = implode('/',array_slice($value,$i));
    }

    return $returnArray;
}


$newValues = stripCommon($values);

echo '<pre>';
var_dump($newValues);
echo '</pre>';

CHỈNH SỬA biến thể của phương thức ban đầu của tôi bằng cách sử dụng array_walk để xây dựng lại mảng

$values = array('/www/htdocs/1/sites/lib/abcdedd',
                '/www/htdocs/1/sites/conf/xyz',
                '/www/htdocs/1/sites/conf/abc/def',
                '/www/htdocs/1/sites/htdocs/xyz',
                '/www/htdocs/1/sites/lib2/abcdedd'
);


function splitArrayValues($r) {
    return explode('/',$r);
}

function rejoinArrayValues(&$r,$d,$i) {
    $r = implode('/',array_slice($r,$i));
}

function stripCommon($values) {
    $testValues = array_map('splitArrayValues',$values);

    $i = 0;
    foreach($testValues[0] as $key => $value) {
        foreach($testValues as $arraySetValues) {
            if ($arraySetValues[$key] != $value) break 2;
        }
        $i++;
    }

    array_walk($testValues, 'rejoinArrayValues', $i);

    return $testValues;
}


$newValues = stripCommon($values);

echo '<pre>';
var_dump($newValues);
echo '</pre>';

BIÊN TẬP

Câu trả lời hiệu quả và tao nhã nhất có thể liên quan đến việc lấy các hàm và phương pháp từ mỗi câu trả lời được cung cấp


1

Tôi sẽ explodecác giá trị dựa trên / và sau đó sử dụng array_intersect_assocđể phát hiện các phần tử chung và đảm bảo chúng có chỉ số tương ứng chính xác trong mảng. Mảng kết quả có thể được kết hợp lại để tạo ra đường dẫn chung.

function getCommonPath($pathArray)
{
    $pathElements = array();

    foreach($pathArray as $path)
    {
        $pathElements[] = explode("/",$path);
    }

    $commonPath = $pathElements[0];

    for($i=1;$i<count($pathElements);$i++)
    {
        $commonPath = array_intersect_assoc($commonPath,$pathElements[$i]);
    }

    if(is_array($commonPath) return implode("/",$commonPath);
    else return null;
}

function removeCommonPath($pathArray)
{
    $commonPath = getCommonPath($pathArray());

    for($i=0;$i<count($pathArray);$i++)
    {
        $pathArray[$i] = substr($pathArray[$i],str_len($commonPath));
    }

    return $pathArray;
}

Điều này chưa được kiểm chứng, nhưng, ý tưởng là $commonPathmảng chỉ bao giờ chứa các phần tử của đường dẫn đã được chứa trong tất cả các mảng đường dẫn đã được so sánh với nó. Khi vòng lặp hoàn tất, chúng tôi chỉ cần kết hợp lại nó với / để có được giá trị true$commonPath

Cập nhật Như đã chỉ ra bởi Felix Kling, array_intersectsẽ không xem xét các đường dẫn có các yếu tố chung nhưng theo các thứ tự khác nhau ... Để giải quyết vấn đề này, tôi đã sử dụng array_intersect_assocthay vìarray_intersect

Cập nhật Mã đã thêm để xóa đường dẫn chung (hoặc đường dẫn chung!) Khỏi mảng.


Điều này có thể sẽ không hoạt động. Hãy xem xét /a/b/c/d/d/c/b/a. Các yếu tố giống nhau, các con đường khác nhau.
Felix Kling,

@Felix Kling Tôi đã cập nhật để sử dụng array_intersect_assoc mà cũng thực hiện một kiểm tra chỉ số
Brendan Bullen

1

Vấn đề có thể được đơn giản hóa nếu chỉ nhìn từ góc độ so sánh chuỗi. Điều này có lẽ nhanh hơn tách mảng:

$longest = $tetris[0];  # or array_pop()
foreach ($tetris as $cmp) {
        while (strncmp($longest+"/", $cmp, strlen($longest)+1) !== 0) {
                $longest = substr($longest, 0, strrpos($longest, "/"));
        }
}

Điều đó sẽ không hoạt động, ví dụ: với mảng tập hợp này ('/ www / htdocs / 1 / sites / conf / abc / def', '/ www / htdocs / 1 / sites / htdocs / xyz', '/ www / htdocs / 1 / sitesjj / lib2 / abcdedd ',).
Artefacto vào

@Artefacto: Bạn đã đúng. Vì vậy, tôi chỉ đơn giản là sửa đổi nó để luôn bao gồm dấu gạch chéo "/" trong so sánh. Làm cho nó không mơ hồ.
mario

1

Có lẽ việc chuyển các thuật toán os.path.commonprefix(m)sử dụng Python sẽ hoạt động?

def commonprefix(m):
    "Given a list of pathnames, returns the longest common leading component"
    if not m: return ''
    s1 = min(m)
    s2 = max(m)
    n = min(len(s1), len(s2))
    for i in xrange(n):
        if s1[i] != s2[i]:
            return s1[:i]
    return s1[:n]

Đó là, uh ... đại loại là

function commonprefix($m) {
  if(!$m) return "";
  $s1 = min($m);
  $s2 = max($m);
  $n = min(strlen($s1), strlen($s2));
  for($i=0;$i<$n;$i++) if($s1[$i] != $s2[$i]) return substr($s1, 0, $i);
  return substr($s1, 0, $n);
}

Sau đó, bạn có thể chỉ thêm từng phần tử của danh sách ban đầu với độ dài của tiền tố chung làm phần bù bắt đầu.


1

Tôi sẽ ném chiếc mũ của mình vào sàn đấu…

function longestCommonPrefix($a, $b) {
    $i = 0;
    $end = min(strlen($a), strlen($b));
    while ($i < $end && $a[$i] == $b[$i]) $i++;
    return substr($a, 0, $i);
}

function longestCommonPrefixFromArray(array $strings) {
    $count = count($strings);
    if (!$count) return '';
    $prefix = reset($strings);
    for ($i = 1; $i < $count; $i++)
        $prefix = longestCommonPrefix($prefix, $strings[$i]);
    return $prefix;
}

function stripPrefix(&$string, $foo, $length) {
    $string = substr($string, $length);
}

Sử dụng:

$paths = array(
    '/www/htdocs/1/sites/lib/abcdedd',
    '/www/htdocs/1/sites/conf/xyz',
    '/www/htdocs/1/sites/conf/abc/def',
    '/www/htdocs/1/sites/htdocs/xyz',
    '/www/htdocs/1/sites/lib2/abcdedd',
);

$longComPref = longestCommonPrefixFromArray($paths);
array_walk($paths, 'stripPrefix', strlen($longComPref));
print_r($paths);

1

Chà, đã có một số giải pháp ở đây nhưng, chỉ vì nó thú vị:

$values = array(
    '/www/htdocs/1/sites/lib/abcdedd',
    '/www/htdocs/1/sites/conf/xyz',
    '/www/htdocs/1/sites/conf/abc/def', 
    '/www/htdocs/1/sites/htdocs/xyz',
    '/www/htdocs/1/sites/lib2/abcdedd' 
);

function findCommon($values){
    $common = false;
    foreach($values as &$p){
        $p = explode('/', $p);
        if(!$common){
            $common = $p;
        } else {
            $common = array_intersect_assoc($common, $p);
        }
    }
    return $common;
}
function removeCommon($values, $common){
    foreach($values as &$p){
        $p = explode('/', $p);
        $p = array_diff_assoc($p, $common);
        $p = implode('/', $p);
    }

    return $values;
}

echo '<pre>';
print_r(removeCommon($values, findCommon($values)));
echo '</pre>';

Đầu ra:

Array
(
    [0] => lib/abcdedd
    [1] => conf/xyz
    [2] => conf/abc/def
    [3] => htdocs/xyz
    [4] => lib2/abcdedd
)

0
$arrMain = array(
            '/www/htdocs/1/sites/lib/abcdedd',
            '/www/htdocs/1/sites/conf/xyz',
            '/www/htdocs/1/sites/conf/abc/def',
            '/www/htdocs/1/sites/htdocs/xyz',
            '/www/htdocs/1/sites/lib2/abcdedd'
);
function explodePath( $strPath ){ 
    return explode("/", $strPath);
}

function removePath( $strPath)
{
    global $strCommon;
    return str_replace( $strCommon, '', $strPath );
}
$arrExplodedPaths = array_map( 'explodePath', $arrMain ) ;

//Check for common and skip first 1
$strCommon = '';
for( $i=1; $i< count( $arrExplodedPaths[0] ); $i++)
{
    for( $j = 0; $j < count( $arrExplodedPaths); $j++ )
    {
        if( $arrExplodedPaths[0][ $i ] !== $arrExplodedPaths[ $j ][ $i ] )
        {
            break 2;
        } 
    }
    $strCommon .= '/'.$arrExplodedPaths[0][$i];
}
print_r( array_map( 'removePath', $arrMain ) );

Điều này hoạt động tốt ... tương tự như mark baker nhưng sử dụng str_replace


0

Có lẽ quá ngây thơ và ngu ngốc nhưng nó hoạt động. Tôi đã sử dụng thuật toán này :

<?php

function strlcs($str1, $str2){
    $str1Len = strlen($str1);
    $str2Len = strlen($str2);
    $ret = array();

    if($str1Len == 0 || $str2Len == 0)
        return $ret; //no similarities

    $CSL = array(); //Common Sequence Length array
    $intLargestSize = 0;

    //initialize the CSL array to assume there are no similarities
    for($i=0; $i<$str1Len; $i++){
        $CSL[$i] = array();
        for($j=0; $j<$str2Len; $j++){
            $CSL[$i][$j] = 0;
        }
    }

    for($i=0; $i<$str1Len; $i++){
        for($j=0; $j<$str2Len; $j++){
            //check every combination of characters
            if( $str1[$i] == $str2[$j] ){
                //these are the same in both strings
                if($i == 0 || $j == 0)
                    //it's the first character, so it's clearly only 1 character long
                    $CSL[$i][$j] = 1; 
                else
                    //it's one character longer than the string from the previous character
                    $CSL[$i][$j] = $CSL[$i-1][$j-1] + 1; 

                if( $CSL[$i][$j] > $intLargestSize ){
                    //remember this as the largest
                    $intLargestSize = $CSL[$i][$j]; 
                    //wipe any previous results
                    $ret = array();
                    //and then fall through to remember this new value
                }
                if( $CSL[$i][$j] == $intLargestSize )
                    //remember the largest string(s)
                    $ret[] = substr($str1, $i-$intLargestSize+1, $intLargestSize);
            }
            //else, $CSL should be set to 0, which it was already initialized to
        }
    }
    //return the list of matches
    return $ret;
}


$arr = array(
'/www/htdocs/1/sites/lib/abcdedd',
'/www/htdocs/1/sites/conf/xyz',
'/www/htdocs/1/sites/conf/abc/def',
'/www/htdocs/1/sites/htdocs/xyz',
'/www/htdocs/1/sites/lib2/abcdedd'
);

// find the common substring
$longestCommonSubstring = strlcs( $arr[0], $arr[1] );

// remvoe the common substring
foreach ($arr as $k => $v) {
    $arr[$k] = str_replace($longestCommonSubstring[0], '', $v);
}
var_dump($arr);

Đầu ra:

array(5) {
  [0]=>
  string(11) "lib/abcdedd"
  [1]=>
  string(8) "conf/xyz"
  [2]=>
  string(12) "conf/abc/def"
  [3]=>
  string(10) "htdocs/xyz"
  [4]=>
  string(12) "lib2/abcdedd"
}

:)


@Doomsday Có một liên kết đến wikipedia trong câu trả lời của tôi ... hãy cố gắng đọc nó trước trước khi bình luận.
Richard Knop,

Tôi nghĩ cuối cùng bạn chỉ so sánh hai con đường đầu tiên. Trong ví dụ của bạn, điều này hoạt động, nhưng nếu bạn xóa đường dẫn đầu tiên, nó sẽ tìm thấy /www/htdocs/1/sites/conf/như một kết hợp chung. Ngoài ra, thuật toán tìm kiếm các chuỗi con bắt đầu từ bất kỳ đâu trong chuỗi, nhưng đối với câu hỏi này, bạn biết rằng bạn có thể bắt đầu ở vị trí 0, điều này làm cho nó đơn giản hơn nhiều.
Jan Fabry
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.