zoukankan      html  css  js  c++  java
  • 字符串面试题系列之四:字符串匹配二

    编译环境

       本系列文章所提供的算法均在以下环境下编译通过。

    【算法编译环境】Federa 8,linux 2.6.35.6-45.fc14.i686
    【处理器】 Intel(R) Core(TM)2 Quad CPU Q9400 @ 2.66GHz
    【内存】 2025272 kB

    前言

        这是字符串匹配的第二道题目。在前面一道题目中,是判断是否存在,那么在本题中则求最短字符串匹配。显然条件更为严格了。

        本系列文章均系笔者所写,难免有一些错误或者纰漏,如果小伙伴们有好的建议或者更好的算法,请不吝赐教。

    正文

    【题目】

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

    【例子】

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

    【分析】

       这道题依然是字符串匹配,但此题是求最短字符串。技巧依然是借助上面的hash _table。那此题我们如何分析呢?首先看到最短两个字,我们会想到什么呢?对!就是先设置一个最小值min,然后每一次处理得到一个值value,如果value比min小,则将min替换成value。就是这种方法。好了,这道题与上面有一个不一样的地方,就是对谁先初始化hash_table。我用红色字标出。且看下面文字算法描述:

    第一步:遍历dest字符串,并且hash_table相应的位置置1,表明该字符存在dest中;
    第二步:遍历src字符串,如果当前字符在dest中,即hash_table相应的值为1,我们每判断一次都做sum++操作,如果sum值等于dest长度,说明一次匹配成功。假设该字串位于front和rear之间。求出其长度,再跟最小长度min对比。如果比min还小,则替换掉min;
    第三步:将front到end之间的字符串复制到结果中,返回之。

    【代码】

    #include <iostream>
    #include <cstring>
    
    void string_min_match( const char * const src,
       const char * const dest, char * result )
    {
       /* srcLen is the length of src string. */
       int srcLen = strlen( src );
       /* destLen is the length of dest string. */
       int destLen = strlen( dest );
       /* front point to start of result string. */
       int front = 0;
       /* rear point to end of result string. */
       int rear = destLen;
        /* because the strings is ascii, so we can
          make a hash table of them and its length is 256.*/
       int hash_table[256] = { 0 };
       /* a counter. */
       int sum = 0;
       /* the minimun length of match string. */
       int min = srcLen;
    
       // init hash_table array.
       for( int i = 0; i < destLen; i++ )
       {
          hash_table[ (int)dest[i] ] ++;
       }
       // handle every character in src string.
       for( int i = 0; i < srcLen; i++ )
       {
          if( sum < destLen )
          {
             if( hash_table[ (int)src[i] ] == 1 )
             {
                sum ++;
                rear ++;
             }
          }
          else
          {
             if( sum > min )
             {
                continue;
             }
             min = sum;
             rear = i;
             front = rear - min;
          }
       }
       // copy the minimun string to result.
       memcpy( result, &src[front], min );
    }
    
    int main( int argc, char ** argv )
    {
       char src[] = "abdcaabcx";
       char dest[] = "abc";
       char result[10] = { 0 };
       string_min_match( src, dest, result );
       std::cout << result << std::endl;
    }

    【结论】

    希望通过自己写这些算法:
    一来督促自己每天学习;
    二来可以锻炼自己的写文章的能力;
    三来可以将这些东西分享给大家。虽然微软都那么多题,且各大网站的面试题五花八门,却没有人做过认真整理。

    作者

       出处:http://www.cnblogs.com/gina

       本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    异常处理
    组合,封装
    自我介绍
    27python更多实例
    28python类代码编写细节
    29python运算符重载
    30python 类的设计
    31python类的高级主题
    32python异常基础
    33python异常编码细节
  • 原文地址:https://www.cnblogs.com/gina/p/3247152.html
Copyright © 2011-2022 走看看