php 最长公共子串,最长公共子串- LCS 算法

LCS (Longest Common Subsequence) 算法

已知字符串str1="网站高并发解决方案",str2="如何解决网站高并发",如何字符串最长公共子串?

lcs 算法原理

将2个字符串采用行列 排列:

如何解决网站高并发

如果行列里面的字符相同,则表示1,否则为0:如何解决网站高并发

网000010000

站000001000

高000000100

并000000010

发000000001

解001000000

决000100000

方000000000

案000000000

同时我们可以优化:

很明显,通过坐标可看到,相同的坐标已经标位1,通过计算连续对角线长度,即可比对出最长字符串.

如果行列里面的字符不相同,则表示为0,否则表示为 该坐标左上角的值后再加1:如何解决网站高并发

网000010000

站000002000

高000000300

并000000040

发000000005

解001000000

决000200000

方000000000

案000000000

在判断字符串时,记录当前最大值与当前最大值坐标,判断完毕之后,即可通过记录的最大坐标获取到最长字符串最后的坐标值

python实现算法:#!/usr/bin/python

# coding:utf-8

def action (str1,str2):

pass

#转为utf-8编码,一个中文字长度占用1

str1 = str1.decode("utf-8")

str2 = str2.decode("utf-8")

data = {}

maxNum = 0

maxLocation = []

#根据长度遍历2个字符串

for i in range(len(str1)):

for j in range(len(str2)):

v1 = str1[i]

v2 = str2[j]

#如果v1等于v2,则该坐标值+1

if v1==v2 :

if data.has_key(i)==False:

data[i] = {}

data[i][j] = 1;

# 判断上一个斜线是否已经是相等了,如果是,则增加上上次的值

if (data.has_key(i-1)) and (data[i-1].has_key(j-1)) :

data[i][j] += data[i-1][j-1]

# 修改最大坐标跟最大数值

if data[i][j]>maxNum:

maxNum = data[i][j]

maxLocation = [i,j]

str = ""

i = maxLocation[0]

j = maxLocation[1]

while True :

if i<0 or j<0:

break

if (data.has_key(i)==False) or (data[i].has_key(j)==False) :

break

str = str1[i]+str

print i,j

i-=1

j-=1

print str,data

result = action("123231aaa测试","12aa测试")

php实现<?php

function test($str1, $str2)

{

//创建一个数组

$data = [];

$str1Arr = mb_str_split($str1);//中文切割数组

$str2Arr = mb_str_split($str2);//中文切割数组

$maxNum = 0;//最大字符串长度

$maxLocation = [];//最大字符串长度坐标

foreach ($str1Arr as $k1 => $v1) {

foreach ($str2Arr as $k2 => $v2) {

//如果值相同

if ($v1 == $v2) {

//判断之前的字符串是否存在

if (isset($data[$k1 - 1][$k2 - 1])) {

$data[$k1][$k2] = 1 + $data[$k1 - 1][$k2 - 1];

} else {

$data[$k1][$k2] = 1;

}

if ($maxNum 

$maxNum = $data[$k1][$k2];

$maxLocation = [$k1, $k2];

}

} else {

$data[$k1][$k2] = 0;

}

}

}

if (empty($maxLocation)) {

$str = '';

} else {

$str = '';

$i = $maxLocation[0];

$j = $maxLocation[1];

while (1) {

if (empty($data[$i][$j])) {

break;

}

$str = $str1Arr[$i] . $str;//因为获取到的字符串是最后一位,所以要反向拼接

$i--;

$j--;

}

}

return $str;

}

function mb_str_split($str){

return preg_split('/(?

}

$a = test('123456789', '98712345324');

echo $a;

本文为仙士可原创文章,转载无需和我联系,但请注明来自仙士可博客www.php20.cn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值