程序1:KMP算法

#include<iostream>   //KMP算法
using namespace std;
#include<string>
#include<typeinfo>

int* getNextArray(string str2)
{
    if(str2.length()==1)
    {
        int* next= new int[1];
        next[0] = -1;
        return next;
    }
    int* next = new int[str2.length()];//注意数组在函数结束返回时只返回一个指针,所以需要将数组开辟在堆区
    next[0]=-1;
    next[1]=0;
    int i=2;
    int cn=0;
    while(i<str2.length())
    {
        if(str2[i-1]==str2[cn])
        {
            next[i++]=++cn;
        }
        else if(cn>0)
        {
            cn=next[cn];
        }
        else
        {
            next[i++]=0;
        }
    }
    return next;
}
int getIndexOf(string str1,string str2)
{
    if(str1.empty() || str2.empty() || str2.length()<1 || str1.length() < str2.length())
    {
        return -1;
    }
    int i1=0;
    int i2=0;
    int* next = getNextArray(str2);
    while(i1<str1.length()&&i2<str2.length())
    {
        if(str1[i1] == str2[i2])
        {
            i1++;
            i2++;
        }
        else if(next[i2]==-1)
        {
            i1++;
        }
        else
        {
            i2=next[i2];
        }
    }
    return i2 == str2.length()?i1-i2:-1;
}

int main()
{
    string s1 = "gjfhgihgibbvkl";
    string s2 = "gihgib";
    cout<<getIndexOf(s1,s2);
    return 0;
}

程序2:Manacher算法

#include<iostream>    //Manacher算法
using namespace std;
#include<string>
#include<typeinfo>
#include<vector>

string manacherString(string str)
{
    string res;
    for(int i =0;i<str.length();i++)
    {
       res+="#";
       res+=str[i];
    }
    res+="#";
    return res;
}

int maxLcpsLength(string str)
{
    if(str.length() == 0)
    {
        return 0;
    }
    string stringArr = manacherString(str);
    int parr[stringArr.length()];  // 回文半径数组
    int C = -1;
    int R = -1;
    int maxD = INT16_MIN;
    for(int i=0;i!=stringArr.length();i++)
    {
        parr[i] = R>i?min(R-i,parr[2*C-i]):1;
        while(i+parr[i] < stringArr.length() && i-parr[i]>-1)
        {
            if(stringArr[i+parr[i]]==stringArr[i-parr[i]])
            {
                parr[i]++;
            }
            else
                break;
        }
        if(i+parr[i]>R)
        {
            R=i+parr[i];
            C=i;
        }
        maxD = max(parr[i],maxD);        
    }
    return maxD-1;
}


int main()
{
    string a = "abcdcbatttabcdc";
    int res = maxLcpsLength(a);
    cout<<res;

    return 0;
}

应用:

#include<iostream>    //Manacher算法的应用
using namespace std;
#include<string>
#include<typeinfo>
#include<vector>

string manacherString(string str)
{
    string res;
    for(int i =0;i<str.length();i++)
    {
       res+="#";
       res+=str[i];
    }
    res+="#";
    return res;
}

string maxLcpsLength(string str)
{
    if(str.length() == 0)
    {
        return 0;
    }
    string stringArr = manacherString(str);
    int parr[stringArr.length()];  // 回文半径数组
    int C = -1;
    int R = -1;
    int maxContainsEnd = -1;
    string res;
    for(int i=0;i!=stringArr.length();i++)
    {
        parr[i] = R>i?min(R-i,parr[2*C-i]):1;
        while(i+parr[i] < stringArr.length() && i-parr[i]>-1)
        {
            if(stringArr[i+parr[i]]==stringArr[i-parr[i]])
            {
                parr[i]++;
            }
            else
                break;
        }
        if(i+parr[i]>R)
        {
            R=i+parr[i];
            C=i;
        }
        if(R==stringArr.length())
        {
            maxContainsEnd = parr[i];
            break;
        } 
    }
    for(int i=0;i<str.length()-maxContainsEnd+1;i++)
    {
        res+=stringArr[i*2+1];
    }
    return res;
}


int main()
{
    string a = "abcd12321";
    string res = maxLcpsLength(a);
    for(int i=0;i<res.length();i++)
    {
        cout<<res[i];
    }

    return 0;
}

程序3:BFPRT算法

#include<iostream>   //BFPRT算法
using namespace std;
#include<string>
#include<typeinfo>
#include<vector>
#include<algorithm>

int getMdeian(int* arr,int begin,int end)
{
    sort(arr+begin,arr+end);
    int sum = end+begin;
    int mid = (sum / 2)+(sum % 2);
    return arr[mid];
}
void swap(int* arr,int small,int cur)
{
    int tmp = arr[small];
    arr[small] = arr[cur];
    arr[cur]=tmp;
}
int* partition(int*arr,int begin,int end,int pivot)
{
    int small=begin-1;
    int cur = begin;
    int big = end+1;
    while(cur!=big)
    {
        if(arr[cur]<pivot)
        {
            swap(arr,++small,cur++);
        }
        else if(arr[cur]>pivot)
        {
            swap(arr,--big,cur);
        }
        else
            cur++;
    }
    int* range =new int[2];
    range[0]=small+1;
    range[1]=big-1;
    return range;
}
int bfprt(int *arr,int begin,int end,int i);   //进行声明
int medianOfMedians(int* arr,int begin,int end)
{
    int num = end-begin+1;
    int offset = num%5==0?0:1;
    int mArr[num /5 +offset];
    for(int i =0;i<num/5+offset;i++)
    {
        int beginI=begin+i*5;
        int endI = beginI+4;
        mArr[i] = getMdeian(arr,beginI,min(end,endI));
    }
    return bfprt(mArr,0,num/5+offset-1,(num/5+offset)/2);
}

int bfprt(int *arr,int begin,int end,int i)
{
    if(begin ==end)
    {
        return arr[begin];
    }
    int pivot = medianOfMedians(arr,begin,end);  //中位数数组中的中位数作为划分值
    int* pivotRange = partition(arr,begin,end,pivot);  //以pivot为划分值返回等于区域的范围
    if(i>=pivotRange[0]&&i<=pivotRange[1])
    {
        return arr[i];
    }
    else if(i<pivotRange[0])
    {
        return bfprt(arr,begin,pivotRange[0]-1,i);
    }
    else 
        return bfprt(arr,pivotRange[1]+1,end,i);
}

int* copyArray(int* arr,int len)   //将原数组拷贝
{
    int* res = new int[len];
    for(int i=0;i<len;i++)
    {
        res[i] = arr[i];
    }
    return res;
}
int getMinKthByBFPRT(int *arr,int len,int K)
{
    int *copyArr = copyArray(arr,len);
    return bfprt(arr,0,len-1,K-1);
}

int main()
{
    int a[]={1,8,9,6,2,4,3,7,5,4,3};
    cout<<getMinKthByBFPRT(a,11,8);
    return 0;
}