首页 > 代码库 > 字符串匹配算法一:查找子字符串

字符串匹配算法一:查找子字符串

【题目】

   就是给一个很长的字符串str 还有一个字符集比如{a,b,c} 找出str里包含{a,b,c}的最短子串。要求O(n)。

【例子】

   字符集是a,b,c,字符串是abdcaabcx,则最短子串为abc。

【分析】

有题意可知,满足要求的字符串只需要包括字符集中的所有字符,并没有顺序要求

当然最容易想到的是做一个字符匹配的过程,但题目要求查找次数为O(n),在思考了几种解决方法后,觉得下面的方案能够达到要求,虽然需要一些额外的空间。

下面我给出自己的解决方案,难免有遗漏的地方,如果路过的朋友有更好的方法,希望不吝赐教

 

1. 将字符集 (char_set )里的字符存储于一个 Hash_table 中,key 为字符本身,值为该字符所在位置,初始化为 -1,遍历 str 的时候,每遇见一个字符,就更新Hash_table

2. 设置额外变量用于记录查找成功的子字符串的最小长度,和子字符串的开头,结尾位置

3. 开始遍历 str,执行以下操作:

    a) sum; // 用于记录 str 中包含了字符集中的字符个数, 如果 sum 等于字符集大小则执行以下程序,否则继续遍历直到满足条件为止

    b) front, end; // front,end 分别存放最小子字符串的首末索引

    c) for cur_char in str; // 用于记录遍历 str 时的当前字符

           如果 cur_char 在字符集 char_set 中,则 Hash_table[cur_char] = str.index(cur_char) // str.index(cur_char) 将cur_char的索引记录

            _f = min(Hash_table); // 找出 Hash_table 的最小值

            _e = max(Hash_table); // 找出 Hash_table 的最大值

           if ( _e - _f ) < min{

                min = (_e - _f);

                front = _f;

       end = _e;

    }

     d) if sum < size(char_set) // 判断字符串 str 查找是否成功, sum 记录了 str 中包含了几个存在于 char_set 中的字符

    return False; 

         else:

            return str[front, end]; // 返回从 front 到 end 位置的子字符串

字符串匹配算法一:查找子字符串