前言: 目标是成为算法大佬,等未来改变了这个目标到时候在说,学到哪写到哪
俺回来了! 之前有点心情颓废,不太振作,现在我胖虎又回来了,这个算法我会根据我的学习进度,尽量保证一周更一次!
文章目录
一. KMP算法: 这是一个字符匹配算法, 由D.E.Knuth,J.H.Morris和V.R.Pratt共同提出来的
- kmp算法其实如果搞清楚了还是比较好理解的,个人想法kmp算法主要解决了主串指针回溯的问题,而且通过记录最大公共前后缀的位置,然后减少子串指针回溯的次数(最好的情况下应该是能减少子串指针回溯的次数的),关键是next[j]中的位置;next[j]中记录最大公共前后缀的位置,每当碰到主串和模式串不匹配时,主串指针不动,模式串指针j=next[j], 并且需要设置next[j]中的初始位置为-1,0,当模式串指针j=next[j]=-1时,则将主串的指针位置往后移一位;
- 代码如下:
c语言版:
//对模式串也就是子串求next数组的值,代码均来自于书上
void GetNext(SqString t, int next[]){
int j, k;
j = 0, k = -1;
next[0] = -1;
while(j < t.length - 1){ // 为啥这里的长度要减一?
if (k == -1 || t.data[j] == t.data[k]){
j++; // 如果前后缀相等,就使得j,k加1;
k++;
next[j] = k; // 并且把k的值存储到next数组中,next数组中存储的纪委最大公共前后缀的值
}
else
k = next[j] // 如果不相等,则将k的值回溯到之前的最大公共前后缀
}
}
// KMP算法
int KMPIndex(SqString s, SqString t){
int next[MaxSize], i = 0, j = 0;
GetNext(t, next);
while (i < s.length && j < t.length){
if(j == -1 || s.data[i] == t.data[j]){
i++;
j++;
}else{
j = next[j];
}
}
// 返回匹配模式串的首字符下表
if(j >= t.length)
return i - t.length;
// 全部都不匹配, 返回-1
else
return -1;
}
python版(是时候自己写了)
```python
def GetNext(strvar):
listvar_next = []
listvar_next[0] = -1
k = -1
for j in strvar:
if k == -1 or j == strvar[k]:
k += 1
listvar_next.append(k)
else:
k = listvar_next[strvar.index(j)]
return listvar_next
def KMPIndex(strvar_1, strvar_2):
next = GetNext(strvar_2)
for i in strvar_1, j in strvar_2:
if i == j :
pass
else:
j = next[strvar_2.index(j)]
if strvar_2.index(j) >= len(strvar_2):
return strvar_1.index(i)- strvar_2.index(j)
else:
return -1
二、约瑟夫闭环算法
- 约瑟夫闭环算法是之前我从另一个博主那里看到的,由于自己也不是计算机专业的,所以可能很多知识都是乱七八糟学了一些,总的来说,约瑟夫环是这样子的,把n个人排成圈,从1开始报数,一直报到m(m<n),循环反复,每次报到m的人就出局,最后剩下一个人
来了,开始准备写我的思路了,也不知道对不对,首先是设置一个单向的循环链表,然后用一个值data记录初始位置,用cnt记录每次报数,当cnt为m的倍数的时候,这个结点就出局,并且还需要一个总数total, 每次出局一个人,总数就减1,当total=1的时候,就是只剩下一个人了,然后就可以结束循环
(累了,俺要休息一下) - 代码实现:
#include<stdio.h>
// 构建单链表结点
typedef struct node {
int data; // 存储位置
struct node *next; //指向下一结点
int cnt = 0; // 初始化cnt
}Linklist;