新学的next_permutation 算法和KMP

来源:互联网 发布:mac苹果系统如何更新 编辑:程序博客网 时间:2024/06/07 09:18

1)next_permutation

这个方法是<algorithm>中的一个函数,可以把这段数组变换为按字典序递增的最小的下一个排列。比如abcd变成abdc。参数是需要求的数组的起始位置和终止位置。可以把这段数组变换为按字典序递增的最小的下一个排列。比如abcd变成abdc。

算法过程是这样的

  1.从最后开始向前面找第一对相邻的数,下标小的那个大于下标大的那个,记录前面的那个数的大小A

2.从最后面开始向前遍历,找到第一个大于A的数,交换两数位置

3.将原数A所在位置之后的字符串反转。

这个算法看完过程之后我的感觉只有一个——搞毛线啊!!

翻到stackflow上搜了一下,终于明白了。

原因:

第一步:

已经成为逆序的排列是没有比它大的排列的,而不是逆序的排列是一定有比它大的排列的。第一步首先从后面开始找到可以增加的字串,就是第一个不排成逆序的字串,记录逆序序列前的第一个数A。要变的就是这个从A到结尾的字符串,前面的都不用变。

第二步:

因为要增加字典序,所以要从逆序列中找一个比A大的数和A调换位置,但是要求字典序增加最小,所以要是比A大的最小的数。因此在这个逆序中从后向前寻找。

第三步:

将原串A后的字符串反转。因为A之后的串是逆序的,字典序呈最大状态,将A于其中一个字符交换位置后,从A到末尾这个字符串肯定比原来字典序要大,这是A与比A大的数交换所致的,所以只需要A之后的串最小只需要将这个逆序串变成顺序串,就是反转。

2)KMP

正常匹配字符串A和B是这样的:

在匹配到位置n的时候,将A中的第一个字符和B中第一个字符匹配,若匹配,A中第二个和B中第二个匹配,若再匹配,那就再看下一个,如果匹配到第m个的时候,不一样的,那就说明字符串从n开始是不能和B匹配的,那就从n+m的位置退回到n+1的位置。

但是这样实际上是有浪费的。

比如我B=abcaba,下标从1开始记录,如果匹配到第6个字符的时候不匹配的,那么A中从第n个位置开始的字符串必然是abaab,下一次其实不必退回到n+1的位置,因为n+3=n,n+4=n+1就是都是ab,所以可以看看a+2和第六个字符是不是一样,若是一样,就继续向下匹配A,若还是不匹配,我找不到可以相等的字串了,所以说明从n的位置A是不能匹配B的,所以A++。

matirx67写的kmp详解,目前所见网上最佳

http://www.matrix67.com/blog/archives/115/


原创粉丝点击