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

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

  • 相关阅读:
    Azkaban的使用
    Azkaban安装
    Kafka 启动失败,报错Corrupt index found以及org.apache.kafka.common.protocol.types.SchemaException: Error reading field 'version': java.nio.BufferUnderflowException
    Kafka 消费者设置分区策略及原理
    Kafka利用Java API自定义生产者,消费者,拦截器,分区器等组件
    zookeeper群起总是有那么几个节点起不来的问题解决
    flume 启动agent报No appenders could be found for logger的解决
    Flume 的监控方式
    Flume 自定义 组件
    Source r1 has been removed due to an error during configuration java.lang.IllegalArgumentException: Required parameter bind must exist and may not be null & 端口无法连接
  • 原文地址:https://www.cnblogs.com/gina/p/3247152.html
Copyright © 2011-2022 走看看