由于上周的算法还没学完,先把上周的算法学了(只是知道怎么实现,是最原始的版本,没有进行优化,大部分题目写不出来)
dijkstra算法:
void dijkstra()
{
for(int i=1;i<n;i++)
{
int k,min1=inf;
for(int j=1;j<=n;j++)
{
if(!flog[j]&&d[j]<min1)
{
k=j;
min1=d[j];
}
}
flog[k]=1;
for(int j=1;j<=n;j++)
{
if(!flog[j]&&min1+a[k][j]<d[j])
d[j]=min1+a[k][j];
}
}
}
该算法是纯dijkstra,没有进行堆优化(采用优先队列),数据大了就超时,由于本周还有其他算法要学,上周的就先清楚该算法是如何实现,至于优化就等我把这周的算法先学完了再回头来优化dijkstra算法
floyf算法:
int floyd(int a[N][N])
{
int i,j,k;
for(k=0;k<N;k++)
{
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
if(a[i][j]>a[i][k]+a[k][j])
a[i][j]=a[i][k]+a[k][j];
}
}
}
}
这个算法就很好理解,就是嵌套循环把所有能从i到j的路径枚举出来,找出最小的就行,代码中k就是从i到j的必经之路(中转),每一个i到j都有N-1个中转站
KMP算法:主要难点就在构建nest数组(当模式串和子串匹配失败时子要跳到什么位置),这构建next数组学了好久(现在也不敢说理解了)
void get_next(char a[],int next[])
{
int i,j=0;
next[0]=0;
for(i=1;a[i];)
{
if(a[i]==a[j])
{
j++;
next[i]=j;
i++;
}
else if(j==0)
{
next[i]=j;
i++;
}
else
j=next[j];
}
}
上述代码就是构建next数组的过程,其中我们要理解next的值是怎么来的,其实next存储的值是前i个字符的前缀和后缀相等的最长长度,这样应该好理解(其实一点也不好理解),由于我刚学懂一点,就不多说明
int kmp(char a[],char b[])
{
int i,j=0;
int next[N]={0};
get_next(b,next);
for(i=0;a[i];)
{
if(a[i]==b[j])
{
i++;
j++;
}
else if(j==0)
i++;
else
j=next[j-1];
if(b[j]=='\0') return i-j+1;
}
return -1;//表示找不到,可以返回其他值(按题目要求来)
}
上述便是kmp算法,当模式串与子串不匹配时根据next数组的值将字串跳到某个位置,使其再线性的时间内找到子串在模式串的位置;
最后总结,这些算法还有优化的地方,就像kijstra算法要用优先队列来进行优化,而kmp算法的next数组还可以进行优化,我认为这些优化需要我更加深入理解这些算法后再进行优化,不然也是优化了也是无用功