kmp里的不需要回溯

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

kmp里的不需要回溯

为什么不需要回溯这个怎么证明

请各位大哥求解一下

加分加分

---------回复--------------

我们看到在简单匹配算法中,当主串和子串的字符比较不相等时,

主串的字符指针ps需返回本趟开始处的下一个字符,而子串的指针pp则回到子串的起始字符,

这种回溯显然是费时的。

如果仔细观察,可以发现这样的回溯常常不是必须的。

所以是不需回溯的。

---------回复--------------

程序实现如下:

#include

#include

#include

#include

#define MAX_LEN_OF_STR 30 // 字符串的最大长度

typedef struct String // 这里需要的字符串数组,存放字符串及其长度{

char str[MAX_LEN_OF_STR]; // 字符数组

int length;// 字符串的实际长度

}String, *PString;

// 得到字符串的next数组

void GetNextArray(PString pstr, int next[])

{assert(NULL != pstr);

assert(NULL != next);

assert(pstr->length > 0);// 第一个字符的next值是-1,因为C中的数组是从0开始的

next[0] = -1;

for (int i = 0, j = -1; i < pstr->length - 1; )

{// i是主串的游标,j是模式串的游标// 这里的主串和模式串都是同一个字符串

if (-1 == j || // 如果模式串游标已经回退到第一个字符

pstr->str[i] == pstr->str[j]) // 如果匹配成功

{// 两个游标都向前走一步

++i;++j;// 存放当前的next值为此时模式串的游标值

next[i] = j;

}else // 匹配不成功j就回退到上一个next值

{j = next[j];}}}

// KMP字符串模式匹配算法

// 输入: S是主串,T是模式串,pos是S中的起始位置

// 输出: 如果匹配成功返回起始位置,否则返回-1

int KMP(PString S, PString T, int pos)

{assert(NULL != S);

assert(NULL != T);

assert(pos >= 0);

assert(pos < S->length);

if (S->length < T->length)

return -1;

printf("主串\t = %s\n", S->str);

printf("模式串\t = %s\n", T->str);

int *next = (int *)malloc(T->length * sizeof(int));// 得到模式串的next数组

GetNextArray(T, next);

int i, j;

for (i = pos, j = 0; i < S->length && j < T->length; ){// i是主串游标,j是模式串游标

if (-1 == j || // 模式串游标已经回退到第一个位置

S->str[i] == T->str[j]) // 当前字符匹配成功

{// 满足以上两种情况时两个游标都要向前进一步

++i;++j;}

else // 匹配不成功,模式串游标回退到当前字符的next值

{j = next[j];}}

free(next);

if (j >= T->length)

{// 匹配成功

return i - T->length;}

else{// 匹配不成功

return -1;}}

---------回复--------------

大哥能证明下么为什么不需要回溯?

---------回复--------------

那为什么要回溯呢??

---------回复--------------

怕漏掉啊

---------回复--------------

/oyd/archive/2008/11/09/3261043.aspx

它的一个重要指导思想是,凡是比较过,被认定为相同的文本字符,绝不再拿出来比。道理上也是能说得通的,因为既然和模式串一部分相同,那么它的信息就已经存在于模式串中了。预处理时,模式串自己和自己的一部分进行比较,存储下自身的相似信息——Next数组。

/2008/04/kmp-next.html

相比较那种最简单的算法而言这里的神奇之处在于一个next函数,由于这个next函数的存在导致我们在模式匹配过程当中某个字符出现失配的情况时不再需要回溯主串当中的指针i 到开始匹配时的位置。所有的数据结构或者算法的书都告诉我们说,之所以不需要回溯这个

i指针是因为在匹配过程当中产生了一些附加的信息,利用这些附加信息就可以得到这样的性能改进。

---------回复--------------

我猜LZ所说的回溯,是往回找的意思,这部分KMP主要是通过Next来处理了,KMP的某些思想和状态机很象。

LZ可以看看构造字母树的自动状态机,就能很好的理解KMP的Next了。

---------回复--------------

《Introduction to Algorithms》里面有证明楼主慢慢看吧!

---------回复--------------

以前也想过~~好多只是推理~~

---------回复--------------

晕,为什么要回溯啊?你游标每次都是从出现不匹配的地方开始,就是说你回溯回去也是不匹配项,从一般心理上来说,不回溯比较好..

---------回复--------------

KMP好难啊,没学好,不太会。。。up LZ

---------回复--------------

为什么要回溯?你拿几个字符串去试一下就会知道这是怎么回事了!当年我也是试出来的。证明还不是在实践基础上来的

---------回复--------------

我同意12 楼的说法,实践出真知

---------回复--------------

你看看为什么平凡的字符串搜索为什么比较慢吧

---------回复--------------

kmp也用回溯阿,只是不是回溯到最前面,而是回溯到next函数指向的地方

为什么可以这么做呢?因为前面那一段匹配与否的信息已经在前一次匹配当中得到了

所以没有必要再做一遍

---------回复--------------

LZ所说的回溯应该是指被匹配串上的回溯吧,被匹配串上的每个字符在关键字所构造出来有穷自动机上进行状态转移,当然不用回溯,

被匹配串上的一个字符如果如果匹配上了一个字符,那自动机向前移动一个状态,如果没匹配上则自动机会跳转到之前的某个状态,也就是失败函数(next数组)所指向的那个状态,再匹配下一个字符,所以无论当前字符是否匹配上,下一个动作都是读下一个字符进行匹配,所谓的回退是自动机的状态向后退方向转移而已

---------回复--------------

KMP依赖的预处理的特征数据,正是这个预处理过程的结果使回溯减到最小,不过也不是完全不回溯

---------回复--------------

相关文档
最新文档