टेट्रिस-आईएनजी एक सरणी


99

निम्नलिखित सरणी पर विचार करें:

/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

इस मामले में - सामान्य आधार पथ का पता लगाने का सबसे छोटा और सबसे सुंदर तरीका क्या है

/www/htdocs/1/sites/

और सरणी में सभी तत्वों से इसे हटा रहा है?

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

4
यह कोशिश करने लायक हो सकता है: en.wikibooks.org/wiki/Algorithm_implementation/Strings/… (मैंने इसे आज़माया और यह काम करता है)।
रिचर्ड नोप

1
Awwww! इस तरह के शानदार इनपुट। मैं हाथ में अपनी समस्या को हल करने के लिए एक ले जाऊंगा, लेकिन मुझे लगता है कि वास्तव में एक उचित स्वीकृत जवाब लेने के लिए, मुझे समाधानों की तुलना करनी होगी। जब तक मुझे ऐसा करने में थोड़ी देर लगेगी, लेकिन मैं निश्चित रूप से करूंगा।
पेक्का

मनोरंजक शीर्षक: D btw: क्यों नहीं मैं तुम्हें नामांकित मध्यस्थों की सूची में मिल सकता है? @ पीका
सूर्यास्त

2
दो साल से कोई जवाब नहीं मिला?
गॉर्डन

1
@Pekka तीन साल के करीब हो रहा है क्योंकि इसका कोई स्वीकृत उत्तर नहीं है :( और यह इतना भयानक शीर्षक है कि मैंने इसे एक पल पहले याद किया और "टेट्राइजिंग ए अरेंज" गुगली की।
कैमिलो मार्टिन

जवाबों:


35

एक फ़ंक्शन लिखें जो longest_common_prefixइनपुट के रूप में दो तार लेता है। फिर इसे किसी भी क्रम में स्ट्रिंग्स पर लागू करें ताकि उनके सामान्य उपसर्ग को कम किया जा सके। चूंकि यह साहचर्य और सराहनीय है इसलिए परिणाम के लिए आदेश मायने नहीं रखता।

यह उदाहरण के अलावा या सबसे बड़े सामान्य भाजक जैसे अन्य बाइनरी संचालन के लिए समान है।


8
+1। पहले 2 स्ट्रिंग्स की तुलना करने के बाद, परिणाम (सामान्य पथ) का उपयोग 3 स्ट्रिंग और इतने पर तुलना करने के लिए करें।
मिलान बाबूसकोव

23

उन्हें एक त्रिकोणीय डेटा संरचना में लोड करें। मूल नोड से शुरू, देखें कि कौन से बच्चे एक से अधिक महान हैं। एक बार जब आप उस जादुई नोड को ढूंढ लेते हैं, तो मूल नोड संरचना को नष्ट कर देते हैं और वर्तमान नोड को जड़ के रूप में रखते हैं।


10
उस ऑपरेशन को नहीं करेगा जो डेटा को ट्राइ ट्री संरचना में लोड करता है जिसका आप वर्णन करते हैं कि सबसे लंबे समय तक सामान्य उपसर्ग खोजने के लिए एल्गोरिथ्म शामिल है, इस प्रकार वास्तव में एक ट्री संरचना का उपयोग करना अनावश्यक है? यानी जब आप पेड़ का निर्माण कर रहे हैं तो आप कई बच्चों के लिए पेड़ की जांच कर सकते हैं। फिर एक पेड़ क्यों? मेरा मतलब है कि यदि आप पहले से ही एक सरणी के साथ शुरू करते हैं। यदि आप एरेज के बजाय स्टोरेज को सिर्फ एक ट्राइ का उपयोग करके बदल सकते हैं तो मुझे लगता है कि यह समझ में आता है।
बेन श्वेन जूल

2
मुझे लगता है कि अगर आप सावधान हैं, तो मेरा समाधान एक ट्राइ के निर्माण की तुलना में अधिक कुशल है।
Starblue

यह उत्तर गलत है। मेरे और अन्य उत्तरों में पोस्ट किए गए तुच्छ समाधान हैं जो O (n) हैं।
अरी रोनेन

@ el.pescado: सबसे खराब स्थिति में स्रोत स्ट्रिंग की लंबाई के साथ ट्राईज़ आकार में चतुष्कोणीय होते हैं।
बिली ओनेल

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;
}

यह अब तक का सबसे अच्छा समाधान है, लेकिन इसमें सुधार की जरूरत है। यह खाते में पिछले लंबे समय तक आम रास्ता नहीं लिया (संभवतः आवश्यकता से स्ट्रिंग के स्थान पर अधिक पुनरावृत्ति), और खाते में पथ नहीं लिया (के लिए तो /usr/libऔर /usr/lib2दे दिया /usr/libसबसे लंबे समय तक आम रास्ता के रूप में है, बजाय /usr/)। मैंने (उम्मीद से) दोनों को तय किया।
गाबे

7

ठीक है, यह देखते हुए कि आप XORइस स्थिति में स्ट्रिंग के सामान्य भागों को खोजने के लिए उपयोग कर सकते हैं । जब भी आप दो बाइट्स को एक समान करते हैं, तो आपको आउटपुट के रूप में एक नल मिलता है। तो हम अपने लाभ के लिए इसका उपयोग कर सकते हैं:

$first = $array[0];
$length = strlen($first);
$count = count($array);
for ($i = 1; $i < $count; $i++) {
    $length = min($length, strspn($array[$i] ^ $first, chr(0)));
}

उस एकल लूप के बाद, $lengthचर स्ट्रिंग की सरणी के बीच सबसे लंबे सामान्य बेसपार्ट के बराबर होगा। फिर, हम पहले तत्व से आम हिस्सा निकाल सकते हैं:

$common = substr($array[0], 0, $length);

आखिर तुमने इसे हासिल कर ही लिया है। एक समारोह के रूप में:

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);
}

ध्यान दें कि यह एक से अधिक पुनरावृत्तियों का उपयोग करता है, लेकिन उन पुनरावृत्तियों को पुस्तकालयों में किया जाता है, इसलिए व्याख्या की गई भाषाओं में यह एक बड़ी दक्षता हासिल होगी ...

अब, यदि आप केवल पूर्ण पथ चाहते हैं, तो हमें अंतिम /चरित्र को छोटा करना होगा । इसलिए:

$prefix = preg_replace('#/[^/]*$', '', commonPrefix($paths));

अब, यह इस तरह के रूप में दो तार काट सकते हैं /foo/barऔर /foo/bar/bazकरने के लिए कट जाएगा /foo। लेकिन यह निर्धारित करने के लिए कि अगले चरित्र / या तो या अंत के स्ट्रिंग के लिए एक और पुनरावृत्ति दौर जोड़ने से कम है , मैं उस के आसपास एक रास्ता नहीं देख सकता ...


3

एक निष्कपट तरीका होगा मार्ग में विस्फोट करना /और क्रमिक प्रत्येक तत्व की तुलना सरणियों में करना। अतः उदाहरणार्थ पहला तत्व सभी सरणियों में खाली होगा, इसलिए इसे हटा दिया जाएगा, अगला तत्व होगा www, यह सभी सरणियों में समान है, इसलिए इसे हटा दिया जाता है, आदि।

कुछ इस तरह (अपरीक्षित)

$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
        }
    }
}

बाद में आपको बस तत्वों को $exploded_pathsफिर से जोड़ना होगा :

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

जो मुझे देता है:

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

यह अच्छी तरह से पैमाने पर नहीं हो सकता है;)


3

ठीक है, मुझे यकीन नहीं है कि यह बुलेट-प्रूफ है, लेकिन मुझे लगता है कि यह काम करता है:

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;
});

यह सरणी में संदर्भ स्ट्रिंग के रूप में पहला मान लेगा। फिर यह संदर्भ स्ट्रिंग पर पुनरावृति करेगा और उसी स्थिति में प्रत्येक स्ट्रिंग की तुलना दूसरे स्ट्रिंग के चार्ट से करेगा। यदि कोई चार मेल नहीं खाता है, तो संदर्भ स्ट्रिंग को चार की स्थिति में छोटा किया जाएगा और अगले स्ट्रिंग की तुलना की जाएगी। फ़ंक्शन तब सबसे छोटी मिलान स्ट्रिंग लौटाएगा।

प्रदर्शन दिए गए स्ट्रिंग्स पर निर्भर करता है। पहले वाला संदर्भ स्ट्रिंग छोटा हो जाता है, कोड जितनी जल्दी खत्म होगा। मैं वास्तव में कोई सूत्र नहीं है कि कैसे एक सूत्र में हालांकि डाल दिया।

मैंने पाया कि स्ट्रिंग्स को क्रमबद्ध करने के लिए आर्टेक्टेक्टो का दृष्टिकोण प्रदर्शन को बढ़ाता है। जोड़ा जा रहा है

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

इससे पहले कि array_reduceप्रदर्शन में काफी वृद्धि होगी।

यह भी ध्यान दें कि यह सबसे लंबे समय तक मिलान वाले प्रारंभिक विकल्प को लौटाएगा , जो अधिक बहुमुखी है लेकिन अभ्यस्त आपको आम रास्ता देगा । आपको दौड़ना होगा

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

परिणाम पर। और फिर आप मानों को निकालने के लिए परिणाम का उपयोग कर सकते हैं

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

जो देना चाहिए:

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

प्रतिक्रिया का स्वागत करते हैं।


3

आप सबसे तेज़ी से उपसर्ग को हटा सकते हैं, प्रत्येक वर्ण को केवल एक बार पढ़ सकते हैं:

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);
}

दरअसल, एक चरित्र-आधारित तुलना सबसे तेज़ होगी। अन्य सभी समाधान "महंगे" ऑपरेटरों का उपयोग करते हैं जो अंत में भी (एकाधिक) चरित्र तुलना करेंगे। पवित्र योएल के शास्त्रों में भी इसका उल्लेख किया गया था !
Jan Fabry

2

यह रैखिक समय जटिलता नहीं होने का डी फायदा है; हालाँकि, अधिकांश मामलों के लिए निश्चित रूप से ऑपरेशन में अधिक समय नहीं लगेगा।

मूल रूप से, चतुर भाग (कम से कम मुझे इसमें कोई दोष नहीं मिला) यहां यह है कि छंटाई के बाद आपको केवल पहले पथ की तुलना अंतिम के साथ करनी होगी।

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>';

संपादित अपने मूल विधि के संस्करण एक array_walk का उपयोग कर सरणी के पुनर्निर्माण के लिए

$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>';

संपादित करें

सबसे कुशल और सुरुचिपूर्ण उत्तर में दिए गए प्रत्येक उत्तर से कार्यों और विधियों को शामिल करने की संभावना है


1

मैं explode/ के आधार पर मानों का उपयोग करूंगा और फिर array_intersect_assocसामान्य तत्वों का पता लगाने के लिए उपयोग करूंगा और यह सुनिश्चित करूंगा कि उनके पास सरणी में सही संगत सूचकांक हो। परिणामी सरणी को सामान्य पथ का निर्माण करने के लिए पुनर्संयोजित किया जा सकता है।

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;
}

यह अप्रयुक्त है, लेकिन, विचार यह है कि $commonPathसरणी में केवल उस पथ के तत्व होते हैं, जो सभी पथ सरणियों में समाहित किए गए हैं, जिनके खिलाफ तुलना की गई है। जब लूप पूरा हो जाता है, तो हम बस इसे पुनः प्राप्त करने के लिए / के साथ सच हो जाता है$commonPath

अपडेट जैसा कि फेलिक्स क्लिंग द्वारा बताया गया है, array_intersectउन रास्तों पर विचार नहीं करेंगे जिनमें आम तत्व हैं, लेकिन अलग-अलग क्रम में हैं ... इसे हल करने के लिए, मैं array_intersect_assocइसके बजाय इस्तेमाल किया गयाarray_intersect

जोड़ा गया कोड सामान्य पथ को हटाने के लिए (या इसे tetris!) और साथ ही सरणी से अपडेट करें


यह शायद काम नहीं करेगा। पर विचार करें /a/b/c/dऔर /d/c/b/a। समान तत्व, विभिन्न पथ।
फेलिक्स क्लिंग

@ फेलिक्स क्लिंग ने मुझे array_intersect_assoc का उपयोग करने के लिए अपडेट किया है जो एक इंडेक्स चेक भी करता है
ब्रेंडन बुल्लेन

1

यदि स्ट्रिंग तुलना कोण से देखा जाए तो समस्या को सरल बनाया जा सकता है। यह संभवतः सरणी-विभाजन से अधिक तेज़ है:

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

इस सेट सरणी ('/ www / htdocs / 1 / sites / conf / abc / def', '/ www / htdocs / 1 / sites / htdocs / xyz', '/ www / htdocs / 1 के साथ काम नहीं करेगा / sitesjj / lib2 / abcdedd ',)।
आर्टीफैक्टो

@Artefacto: आप सही थे। तो मैंने बस इसे संशोधित किया है हमेशा तुलना में एक अनुगामी स्लेश "/" शामिल करें। इसे गैर-अस्पष्ट बनाता है।
मारियो

1

शायद एल्गोरिथ्म पायथन के os.path.commonprefix(m)उपयोग को पोर्ट करना काम करेगा?

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]

वह है, उह ... कुछ पसंद है

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);
}

उसके बाद आप मूल सूची के प्रत्येक तत्व को स्टार्ट ऑफसेट के रूप में सामान्य उपसर्ग की लंबाई के साथ जोड़ सकते हैं।


1

मैं अपनी टोपी रिंग में फेंक दूंगा ...

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);
}

उपयोग:

$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

खैर, यहां पहले से ही कुछ समाधान हैं लेकिन, सिर्फ इसलिए कि यह मजेदार था:

$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>';

आउटपुट:

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 ) );

यह ठीक काम करता है ... मार्क बेकर के समान लेकिन str_replace का उपयोग करता है


0

शायद बहुत भोला और नीच लेकिन यह काम करता है। मैंने इस एल्गोरिथ्म का उपयोग किया है :

<?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);

आउटपुट:

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 मेरे जवाब में विकिपीडिया की एक कड़ी है ... टिप्पणी करने से पहले इसे पढ़ने की कोशिश करें।
रिचर्ड नोप

मुझे लगता है कि अंत में आप केवल पहले दो रास्तों की तुलना करते हैं। आपके उदाहरण में यह काम करता है, लेकिन यदि आप पहला रास्ता निकालते हैं, तो यह /www/htdocs/1/sites/conf/एक आम मैच के रूप में मिलेगा । इसके अलावा, एल्गोरिथ्म स्ट्रिंग में कहीं भी शुरू होने वाले सबस्ट्रिंग की खोज करता है, लेकिन इस प्रश्न के लिए आप जानते हैं कि आप स्थान 0 पर शुरू कर सकते हैं, जो इसे बहुत सरल बनाता है।
जन फैब्री
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.