php实现最小公共子串,JavaScript语言描述的最大公共子串问题

求最大公共子串,常见的做法是使用矩阵。假设有字符串:abcdefg和字符串abcd,则可构成如下矩阵。

a b c d e f g

a 1 0 0 0 0 0 0

b 0 1 0 0 0 0 0

c 0 0 1 0 0 0 0

d 0 0 0 1 0 0 0

对两个字符串的每一项都进行比较,若匹配则该项为1,不匹配则为0。然后求出对角线最长为1的那一段序列,即为最大公共子串。看上面的分开,似乎得使用二维数组了,在两个字符串都较大的情况下不是很划算,是否可以进一步优化?

可以,需要改变一下策略,如果该项匹配,则该项的值为再设为1,而是其对角线a[i-1, j-1](i > 1 && j > 1)的值+1,这样便可以只使用一个一维数组。

以一个字符串作为“行”,另一个作为“列”,比较两个字符串各项的值,用另外一个变量记录数组的最大值和字符串的起始位置。代码如下:

function LCS(str1, str2) {

if (str1 === "" || str2 === "") {

return "";

}

var len1 = str1.length;

var len2 = str2.length;

var a = new Array(len1);

var maxLen = 0;

var maxPos = 0;

for (var i = 0; i < len1; i++) { //行

for (var j = len2 - 1; j >= 0; j--) {//列

if (str1.charAt(j) == str2.charAt(i)) {

if (i === 0 || j === 0) {

a[j] = 1;

} else {

a[j] = a[j - 1] + 1;

}

} else {

a[j] = 0;

}

if (a[j] > maxLen) {

maxLen = a[j];

maxPos = j;

}

}

}

return str1.substr(maxPos - maxLen + 1, maxLen);

}

但代码其实并不是最优的,为什么?因为上面的写法必须等待两层循环都完成。有没有相对更快一些的方法呢?

设有字符串a、b,其长度分别为len1、len2,其公共字子串一定是 <= Math.min(len1, len2),而且子串必定连续,且一定是a、b的子串。

function findMaxSubStr(s1,s2){

var str= "",

L1=s1.length,

L2=s2.length;

if (L1>L2){

var s3=s1;

s1=s2;

s2=s3;

s3 = null;

L1=s2.length;

L2 = s1.length;

}

for (var i=L1; i > 0; i--) {

for (var j= 0; j <= L2 - i && j < L1; j++){

str = s1.substr(j, i);

if (s2.indexOf(str) >= 0) {

return str;

}

}

}

return "";

}

先比较s1、s2的长度,然后取较短的字符串作为。substr(idex, len),所以拿较短的串取其子串,然后判断它是否在较长的字符串中存在,如果存中则直接返回,否则再取下一位。

完整示例:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 最小二乘法是用来拟合一条直线,以使拟合出来的直线与给定的数据点的误差的平方和最小。下面是一种使用 JavaScript 实现最小二乘法的算法: 1. 定义一个函数,接收给定的数据点。 2. 计算给定数据点的平均 x 和 y 值。 3. 计算给定数据点的 x 和 y 的方差和协方差。 4. 使用协方差和方差计算直线的斜率和截距。 5. 返回直线方程 y = kx + b。 以下是一个 JavaScript 实现的示例: ``` function leastSquares(points) { let sumX = 0; let sumY = 0; let sumXX = 0; let sumXY = 0; let n = points.length; for (let i = 0; i < n; i++) { let x = points[i][0]; let y = points[i][1]; sumX += x; sumY += y; sumXX += x * x; sumXY += x * y; } let m = (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX); let b = (sumY - m * sumX) / n; return [m, b]; } ``` 在使用最小二乘法之前,请确保已经了解了数学原理。 ### 回答2: 最小二乘法是一种常用的数据拟合算法,可以用于找到最适合一组数据的直线拟合。在JavaScript中,我们可以通过以下步骤实现最小二乘法的直线拟合: 1. 获取数据集:首先,需要获取一组包含多个数据点的数据集。可以使用数组来表示,例如: ``` var dataset = [[x1, y1], [x2, y2], [x3, y3], ...]; ``` 2. 计算数据集的平均值:使用循环遍历数据集,分别计算x和y的平均值,即x的平均值为`sumX / dataset.length`,y的平均值为`sumY / dataset.length`。 3. 计算斜率b:使用循环遍历数据集,根据最小二乘法的公式计算斜率b的值,即: ``` var numerator = 0; var denominator = 0; for (var i = 0; i < dataset.length; i++) { var x = dataset[i][0]; var y = dataset[i][1]; numerator += (x - meanX) * (y - meanY); denominator += Math.pow((x - meanX), 2); } var b = numerator / denominator; ``` 其中,`meanX`和`meanY`分别为步骤2中计算得到的平均值。 4. 计算截距a:使用步骤2中计算的平均值和步骤3中计算的斜率b,即: ``` var a = meanY - b * meanX; ``` 5. 创建拟合直线:将步骤4中计算得到的截距a和斜率b组合成一条直线的方程,例如: ``` var equation = "y = " + b.toFixed(2) + "x + " + a.toFixed(2); ``` 这样,我们就成功用JavaScript实现了最小二乘法的直线拟合。 ### 回答3: 最小二乘法是一种常用的参数估计方法,可以用于拟合线性模型。在JavaScript中,可以通过以下步骤实现最小二乘法直线拟合: 1. 收集数据:首先,需要收集一组x和y的数据。这些数据可以来自实验测量、观测或其他来源。 2. 计算均值:计算x和y的均值,分别记为x_mean和y_mean。 3. 计算差值:分别计算x和y与均值之差的数组,分别记为x_diff和y_diff。 4. 计算平方差值:将x_diff中的每个元素平方,得到x_diff_squared数组;将y_diff中的每个元素平方,得到y_diff_squared数组。 5. 计算x与y之间的乘积:将x_diff中的每个元素与y_diff中对应的元素相乘,得到xy_diff数组。 6. 计算斜率:计算xy_diff数组的和除以x_diff_squared数组的和,得到斜率slope。 7. 计算截距:将y_mean减去斜率乘以x_mean,得到截距intercept。 8. 输出结果:将斜率slope和截距intercept作为最小二乘法直线拟合的结果。 这是一个简单的JavaScript实现,可以使用循环和基本数学运算符来计算数组和。实现后,可以使用实际数据进行测试,看看拟合效果如何。需要注意的是,这只适用于线性关系的数据,对于非线性的数据,最小二乘法可能无法得到准确的拟合结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值