1. 程式人生 > >演算法 -- 求最長公共字串&PHP

演算法 -- 求最長公共字串&PHP

本文是利用PHP,求最長公共字串。

思路:利用動態規劃和矩陣的思想。

動態規劃就是用空間的代價來爭取時間,將中間結果儲存下來,後面迴圈使用供,減少重複計算次數。

矩陣思想:定義一個矩陣,寬和高分別為兩個字串的長度。從上到下、從左到右逐個掃描,每次掃描要比較矩陣中每個點對應的行列字元是否相等, 相等的話等於左上鄰+1,不相等則置為0。

時間複雜度:矩陣中的長和寬的乘積即為複雜度。複雜度為O(mn)。

如兩個字串:“abcd”和“ebc”。如下圖所示:

  a b c d
e 0 0 0 0
b 0 1 0 0
c 0 0 2 0

注:為什麼相等的話要等於左上鄰+1?因為左上鄰代表兩個字串的各自前一個元素,如果前一個元素是對應相等的,且當前位置的對應元素也相等,那麼公共字串的長度需要+1,因此等於左上鄰+1。

求最長公共字串的程式碼如下:

function getLongestSameStr($a, $b)
{
    if (empty($a) || empty($b)) return 0;
    // 判斷字串是否包含
    if (strlen($a) > strlen($b)) {
        if (strstr($a, $b) != '') return $b;
    } else {
        if (strstr($b, $a) != '') return $a;
    }

    $same_arr = [];// 矩陣
    $same_str = [];// 所有相同的字串
    $a_len = strlen($a);
    $b_len = strlen($b);
    $longest_str = 0;// 最長的字串
    for ($i = 0; $i < $a_len; $i++) {
        for ($j = 0; $j < $b_len; $j++) {
            if ($a[$i] == $b[$j]) {
                if ($i > 0 && $j > 0) {
                    $same_arr[$i][$j] = $same_arr[$i - 1][$j - 1] + 1;
                } else {
                    $same_arr[$i][$j] = 1;
                }
                // 所有相同長度的字串
                $longest_str = max($longest_str, $same_arr[$i][$j]);
                $same_str[] = substr($a, $i - $same_arr[$i][$j] + 1, $same_arr[$i][$j]);
            } else {
                $same_arr[$i][$j] = 0;
            }
        }
    }
    // 最長的相同字串
    $longest_same_str = [];
    foreach ($same_str as $v) {
        if ($longest_str == strlen($v)) {
            $longest_same_str[] = $v;
        }
    }
    return $longest_same_str;
}

例項如下,隨便定義兩個字串,$a和$b,呼叫此函式。

$a = '11111111abced3212334123wqeqwe156123456789';
$b = '111222abced3213346262qweqweqweqwe64123456789';
$aaa = getLongestSameStr($a, $b);
echo '<pre>';
print_r($aaa);

輸出結果為:

Array
(
    [0] => 123456789
)

假如設定特殊的字串,如$a和$b有兩個公共的相同長度的字串,呼叫次函式後會出現兩個字串。

$a = '11111111abced321334123wqeqwa12345678901';
$b = '111222abced3213346262qweqweqweqweb12345678901';
$aaa = getLongestSameStr($a, $b);
echo '<pre>';
print_r($aaa);

結果如下:

Array
(
    [0] => abced321334
    [1] => 12345678901
)

達到了預期的效果。

此演算法由本人自行編寫,並除錯成功,轉載請標註,謝謝!

歡迎補充!

千而の大獅子!