最长公共子串问题 Longest Common Substring LCST 动态规划

* 题目:

 给定2个字符串$str1, $str2, 返回2个字符串的最长公共子串

e.g.

$str1 = "1AB2345CD";

$str2 = "12345EF"

返回: "2345"

要求: 如果$str1 长度为M, $str2长度为N, 实现时间复杂度为O(MxN), 额外空间复杂度为O(1)的方法
 

* LCST.php

<?php

/**
 * Created by PhpStorm.
 * User: Mch
 * Date: 2018/12/1
 * Time: 10:29 PM
 */
class LCST {
    /** @var  string */
    private $str1;
    /** @var  string */
    private $str2;

    public function __construct(string $str1, string $str2) {
        $this->str1 = $str1;
        $this->str2 = $str2;
    }

    private function getdp() : \SplFixedArray {
        $len1 = strlen($this->str1);
        $len2 = strlen($this->str2);

        $dp = new \SplFixedArray($len1);
        for ($i = 0; $i < $dp->getSize(); $i++) {
            $dp[$i] = new \SplFixedArray($len2);
        }
        for ($i = 0; $i < $len1; $i++) {
            if ($this->str1[$i] === $this->str2[0]) {
                $dp[$i][0] = 1;
            }
        }
        for ($j = 1; $j < $len2; $j++) {
            if ($this->str1[0] === $this->str2[$j]) {
                $dp[0][$j] = 1;
            }
        }
        for ($i = 1; $i < $len1; $i++) {
            for ($j = 1; $j < $len2; $j++) {
                if ($this->str1[$i] === $this->str2[$j]) {
                    $dp[$i][$j] = $dp[$i-1][$j-1] + 1;
                }
            }
        }
        return $dp;
    }

    public function lcst1() : string {
        $s1 = $this->str1;
        $s2 = $this->str2;
        if (is_null($s1) || is_null($s2) || empty($s1) || empty($s2)) {
            return "";
        }
        $dp = $this->getdp();
        $end = 0;
        $max = 0;
        $len1 = strlen($s1);
        $len2 = strlen($s2);
        for ($i = 0; $i < $len1; $i++) {
            for ($j = 0; $j < $len2; $j++) {
                if ($dp[$i][$j] > $max) {
                    $end = $i;
                    $max = $dp[$i][$j];
                }
            }
        }
        return substr($s1, $end-$max+1, $max);
    }

    public function lcst2() : string {
        $s1 = $this->str1;
        $s2 = $this->str2;
        if (is_null($s1) || is_null($s2) || empty($s1) || empty($s2)) {
            return "";
        }
        $len1 = strlen($s1);
        $len2 = strlen($s2);
        $row = 0;
        $col = $len2 - 1;
        $max = 0;
        $end = 0;
        while ($row < strlen($s1)) {
            $i = $row;
            $j = $col;
            $len = 0;
            while ($i < $len1 && $j < $len2) {
                if ($s1[$i] !== $s2[$j]) {
                    $len = 0;
                } else {
                    $len++;
                }
                if ($len > $max) {
                    $end = $i;
                    $max = $len;
                }
                $i++;
                $j++;
            }
            if ($col >0) {$col--;}
            else {$row++;}
        }
        return substr($s1, $end-$max+1, $max);
    }

}

* index.php

<?php
/**
 * Created by PhpStorm.
 * User: Mch
 * Date: 2018/12/1
 * Time: 10:58 PM
 */
function __autoload($className) {
    include $className.'.php';
}

$str1 = "1AB2345CD";
$str2 = "12345EF";
$lcst = new LCST($str1, $str2);
echo $lcst->lcst1().PHP_EOL;
echo $lcst->lcst2().PHP_EOL;

猜你喜欢

转载自blog.csdn.net/fareast_mzh/article/details/84679733