字符串算法

KMP算法

Next数组 Next[i]表示:当在i位置失配时,i应该跳回的位置,显然Next[0]=-1

void getNext(char *p)
{
    next[0]=-1;
    int len=strlen(p);
    int j=0;
    int k=-1;
    while(j<len-1)
    {
        if(k==-1||p[j]==p[k])
            next[++j]=++k;
        else k=next[k];
    }
}
//优化后的kmp算法
void getNext(char* p)
{
    next[0]=-1;
    int len=strlen(p);
    int j=0;
    int k=-1;
    while(j<len-1)
    {
        if(k==-1||p[j]==p[k])
        {
            if(p[++j]==p[++k])
                next[j]=next[k];
            else next[j]=k;
        }
        else k=next[k];
    }
}
int kmp(char* t,char* p)
{
    int n=strlen(t);
    int m=strlen(p);
    int i=0;
    int j=0;
    getNext(p);
    while(i<n&&j<m)
    {
        if(j==-1||t[i]==p[j])
        {
            i++;
            j++;
        }
        else{
            j=next[j];
        }
    }
    if(j==m)
        return i-j;
    else return -1;
}

Manacher(马拉车)算法

马拉车用于解决最长回文子串问题,重点是子串,而不是子序列,想了解最长回文子序列的可以看下这篇博客传送门。对于这种问题,当然最简单粗暴的方法就是暴力求解,但太暴力也不好,毕竟会TLE。所以对于求最长回文子串的问题有一种神奇的算法——马拉车算法,神奇就神奇在时间复杂度为O(n)。

我先说一下大概思路,就是用一个Len[i]数组去存第i个位置到mx位置的长度,然后用id记录上一次操作的位置,mx标记上一次的最长子串的最右端,然后依次去递推。不太好理解(花了好几个小时才懂),现在看不懂没关系,我尽量讲的详细点。

以hihoCoder的一道裸题为例,只要能AC就差不多懂了,题目链接:传送门

先定义一个字符串s = “ababc”,因为对于回文字符串来说有对称轴,比如说aba就是以b作为对称轴,那么当字符串长度为偶数的时候,对称轴就不是唯一的整数位了。所以我们要对原字符串

做一个预处理,在每个字符左右都加上一个特殊字符,这里我用’#’,那么处理后的字符串str就是#a#b#a#b#c#了,不管原字符串长度是奇数还是偶数,处理后的长度都变成偶数了。然后还需要在这个str的最前面加一个不同于之前的特殊字符的特殊字符,这里我用了’%’(因为在后面的while循环中在匹配字符的时候可能会越界)。这样预处理操作就完了,最后的字符串str就是%#a#b#a#b#c#了。

首先需要明白的是,我定义的mx是上一次操作的最长回文子串的最右端,我解释一下,比如说ababa,第一次对i=2操作的时候,会计算出他的最回文子串为aba(长度为3),则在这次操作结束后mx的位置就是4,也就是aba的下一位。而我定义的id是上一次操作的位置,也就是i的位置,还以刚才的例子为例,在对i=2操作结束后,id的位置就是2。姑且先这么理解,知道他是什么就行,后面再去思考。

Len数组里存的是第i个位置到mx位置的长度,比如说还是ababa,当i=2的时候,可以计算出aba是它此时的最长回文子串,那么mx的位置就是aba的下一位,那Len[2]存的就是mx - i了。最重要的就是Len数组,所以这点一定要弄明白,Len存的是,当前这个位置到它的最长回文子串的最右端的距离(也就是mx的位置)。在str字符串中,Len[i] = 2*Len[i] - 1(因为有特殊字符),在s字符串中Len[i] = mx - id + 1。
知道这些后,开始进入正题,先看下核心代码。

#include <iostream>
#include <cstring>
#include <cstdio>
#define MAX 110100
int Len[2*MAX];
char s[MAX];
char str[2*MAX];
int mx,id;
int length;
using namespace std;
void init()
{
    int k=0;
    str[k++]='$';
    for(int i=0;i<length;i++)
    {
        str[k++]='#';
        str[k++]=s[i];
    }
    str[k++]='#';
    length=k;
}
int Manacher()
{
    int sum=0;
    mx=0;
    for(int i=1;i<length;i++)
    {
        if(mx>i)
            Len[i]=min(Len[2*id-i],mx-i);
        else Len[i]=1;
        while(str[i+Len[i]]==str[i-Len[i]])
            Len[i]++;
        if(i+Len[i]>mx)
        {
            mx=i+Len[i];
            id=i;
        }
        sum=max(sum,Len[i]);
    }
    return sum-1;
}
int main()
{
    while(~scanf("%s",s))
    {
        length=strlen(s);
        init();
        printf("%d\n",Manacher());
    }
}

最小表示法

我们这里要i = 0,j = 1,k = 0,表示从i开始k长度和从j开始k长度的字符串相同(i,j表示当前判断的位置)

当我们str[i] == str[j]时,根据上面k的定义,我们的需要进行k+1操作

当str[i] > str[j]时,我们发现i位置比j位置上字典序要大,那么不能使用i作为开头了,我们要将i向后移动,移动多少呢?有因为i开头和j开头的有k个相同的字符,那么就执行 i = i + k +1

相反str[i] < str[j]时,执行:j = j + k +1

最终i和j中较小的值就是我们最终开始的位置

相反如果是最大表示法的话,我们就要求解字典序最大的字符串,那么我们只需要在执行第二或第三个操作时选择较大的那个位置较好了

int Get_Min()
{
    int n=strlen(s);
    int i=0,j=1;
    int k=0;
    int t;
    while(i<n&&j<n&&k<n)
    {
        t=s[(i+k)%n]-s[(j+k)%n];
        if(!t)
            k++;
        else{
            if(t>0)
                i+=k+1;   //j+=k+1
            else j+=k+1;  //i+=k+1
            if(i==j)
                j++;
            k=0;
        }
    }
    return min(i,j);
}

LCS(最长公共子序列)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像识别技术在病虫害检测中的应用是一个快速发展的领域,它结合了计算机视觉和机器学习算法来自动识别和分类植物上的病虫害。以下是这一技术的一些关键步骤和组成部分: 1. **数据收集**:首先需要收集大量的植物图像数据,这些数据包括健康植物的图像以及受不同病虫害影响的植物图像。 2. **图像预处理**:对收集到的图像进行处理,以提高后续分析的准确性。这可能包括调整亮度、对比度、去噪、裁剪、缩放等。 3. **特征提取**:从图像中提取有助于识别病虫害的特征。这些特征可能包括颜色、纹理、形状、边缘等。 4. **模型训练**:使用机器学习算法(如支持向量机、随机森林、卷积神经网络等)来训练模型。训练过程中,算法会学习如何根据提取的特征来识别不同的病虫害。 5. **模型验证和测试**:在独立的测试集上验证模型的性能,以确保其准确性和泛化能力。 6. **部署和应用**:将训练好的模型部署到实际的病虫害检测系统中,可以是移动应用、网页服务或集成到智能农业设备中。 7. **实时监测**:在实际应用中,系统可以实时接收植物图像,并快速给出病虫害的检测结果。 8. **持续学习**:随着时间的推移,系统可以不断学习新的病虫害样本,以提高其识别能力。 9. **用户界面**:为了方便用户使用,通常会有一个用户友好的界面,显示检测结果,并提供进一步的指导或建议。 这项技术的优势在于它可以快速、准确地识别出病虫害,甚至在早期阶段就能发现问题,从而及时采取措施。此外,它还可以减少对化学农药的依赖,支持可持续农业发展。随着技术的不断进步,图像识别在病虫害检测中的应用将越来越广泛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值