最长公共子串(Longest Common Substring ,简称LCS)问题,是指求给定的一组字符串长度最大的共有的子串的问题。例如字符串”abcb”,”bca”,”acbc”的LCS就是”bc”。

下面给出php语言的代码实现:

<?php
$str = array();
$k = 0;
$minlen = 1000;
$flag = 0;
$n = 0;

function match($start, $end, $n)   //最短字符串中的起点下标、终点下标,字符串总数
{
    global $str, $k;

    for($i=0; $i<$n; $i++)
    {
        if($i==$k)
            continue;
        $len=strlen($str[$i]);
        //str[i]字符串可以组成len-1-end+start个长度为end-start的连续子串
        for($j=0; $j<=$len-1-$end+$start; $j++)
        {
            for($p=$start,$h=$j; $p<=$end; $p++,$h++)    //顺序判断子串
            {
                if($str[$k][$p] != $str[$i][$h])       //不等即跳出
                    break;
            }
            if($p > $end)                   //如果全部相等,则匹配成功,终止
                break;
                
/*
            for($p=$end,$h=$j; $p>=$start; $p--,$h++)             //逆序判断子串
            {
                if($str[$k][$p] != $str[$i][$h])       //不等即跳出
                    break;
            }
            if($p < $start)                   //如果全部相等,则匹配成功,终止
                break;
*/

        }
        if($j > $len-1-$end+$start)    //如果搜索完毕都没终止,即无匹配
            return 0;
    }
    return 1;
}

function read() 
{
    fscanf(STDIN, "%s\n", $input);
    $input = trim($input);
    return $input;
}

function execute()
{
    global $str, $k, $minlen, $flag, $n;
    $start = microtime(true);
    
    for($i=0; $i<$minlen; $i++)    //对最短字符串的连续字串进行匹配查找
    {
        for($j=0; $j<=$i; $j++)
        {
            if(match($j, $j+$minlen-1-$i, $n))    //子串是否匹配
            {
                $flag=1;
                break;
            }
        }
        if($flag==1)
            break;
    }
    if($flag==1)
    {
        echo iconv('utf-8', 'gbk', "一条最长公共子串为:".substr($str[$k], $j, $minlen-$i)."\n");
        
        echo iconv('utf-8', 'gbk', "其长度为:".($minlen-$i)."\n");
    }
    else
    {
        echo iconv('utf-8', 'gbk', "无最长公共子串\n");
    }
    
    $finish = microtime(true);  
    echo iconv('utf-8', 'gbk', "程序运行时间为:".($finish-$start)."秒\n");    
}

function test()
{
    global $str, $k, $minlen, $flag, $n;
    
    $str = array(
        'abcdefghijklmn',
        'cdefgijklm',
        'defgjklm',
        'efgjkl',
        'gjkl',
        'opqrsgjkltuvwxyz',
        'opqrstugjklvwxy',
        'opqrstgjkluv',
        'opgjklq',
        'opqgjklrstu',
        'vwxgjkly',
        'vwxgjklyz',
        'vwxgjklyzabce',
        'vwxgjklyzvdsae',
        'vwxgjklyzdadadada',
        'vxxxeaewxgjklyz',
        'vwxaaaaaaaaagjklyz',
        'cafaefagagtvwxgjklyz',
        'addewafafafavwxgjklyz'
    );
    $n = count($str);
    
    for($i=0; $i<$n; $i++)
    {
        $len = strlen($str[$i]);
        if($len < $minlen)
        {
            $minlen = $len;      //保存最短字符串的长度
            $k = $i;             //保存最短字符串的序号
        }
    }
    
    execute();

    return 0;    
}

function main()
{
    global $str, $k, $minlen, $flag, $n;
    
    echo iconv('utf-8', 'gbk', "请输入字符串个数\n");
    $n = read();
    
    for($i=0; $i<$n; $i++)
    {
        echo iconv('utf-8', 'gbk', "请输入第".($i+1)."个字符串\n");
        
        $str[$i] = read();
        $len = strlen($str[$i]);
        if($len < $minlen)
        {
            $minlen = $len;      //保存最短字符串的长度
            $k = $i;             //保存最短字符串的序号
        }
    }
    
    execute();

    return 0;
}

if(!empty($argv[1]) && $argv[1]=='test')
{
    test();    
}
else
{
    main();
}

运行结果:

wKiom1U-9CeQ3s4fAADwnAoci5E091.jpg