zoukankan      html  css  js  c++  java
  • 13 字符串查找

    原题网址: http://www.lintcode.com/zh-cn/problem/strstr/#

    对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始)。如果不存在,则返回 -1

    说明

    在面试中我是否需要实现KMP算法?

    • 不需要,当这种问题出现在面试中时,面试官很可能只是想要测试一下你的基础应用能力。当然你需要先跟面试官确认清楚要怎么实现这个题。
    样例

    如果 source = "source" 和 target = "target",返回 -1

    如果 source = "abcdabcdefg" 和 target = "bcd",返回 1

    挑战 

    O(n2)的算法是可以接受的。如果你能用O(n)的算法做出来那更加好。(提示:KMP)

     

    方法一:遍历source,找到第一个与target[0]相同的字符source[j],然后按照target大小依次循环对比,若有一处字符不等,跳出当前循环继续寻找,否则返回j。

     1 class Solution {
     2 public:
     3     /*
     4      * @param source: source string to be scanned.
     5      * @param target: target string containing the sequence of characters to match
     6      * @return: a index to the first occurrence of target in source, or -1  if target is not part of source.
     7      */
     8     int strStr(const char *source, const char *target) {
     9         // write your code here
    10         if (source==NULL||target==NULL)
    11     {
    12         return -1;
    13     }
    14     int sizes=strlen(source);
    15     int sizet=strlen(target);
    16     if (sizet==0)
    17     {
    18         return 0;
    19     }
    20     if (sizet>sizes)
    21     {
    22         return -1;
    23     }
    24         for (int j=0;j<sizes;j++)
    25         {
    26             if (target[0]==source[j])
    27             {
    28                 int tempIndex=j;//j还要继续向后移动对比,可以通过临时变量来完成;
    29                 bool flag=true;
    30                 if ((sizes-j)<sizet) //j开始source中剩余字符少于sizet,返回-1;
    31                 {
    32                     return -1;
    33                 }
    34                  int i=1;
    35                 while(i<sizet)
    36                 {
    37                     if (target[i++]!=source[++tempIndex])
    38                     {
    39                         flag=false;
    40                         break;
    41                     }
    42                 }
    43                 if (flag)
    44                 {
    45                     return j;
    46                 }
    47                             
    48             }
    49             
    50         }
    51         return -1;
    52     }
    53 };

    方法2,KMP

    参考:

    https://www.cnblogs.com/libaoquan/p/6980182.html

    https://www.cnblogs.com/Smallhui/p/5540855.html

    史上最浅显易懂的KMP算法讲解:字符串匹配算法   多看几遍,注意代码中的next数组存储的是前后缀公共长度减一

    KMP算法最浅显理解——一看就明白

    这个KMP算法真的是看了一上午加一下午才勉强实现出来,脑仁疼……

     1 class Solution {
     2 public:
     3     /*
     4      * @param source: source string to be scanned.
     5      * @param target: target string containing the sequence of characters to match
     6      * @return: a index to the first occurrence of target in source, or -1  if target is not part of source.
     7      */
     8      
     9      
    10     int strStr(const char *source, const char *target) {
    11         // write your code here
    12         if (source==NULL||target==NULL)
    13     {
    14         return -1;
    15     }
    16     int sizes=strlen(source);
    17     int sizet=strlen(target);
    18     if (sizet==0)
    19     {
    20         return 0;
    21     }
    22     if (sizet>sizes)
    23     {
    24         return -1;
    25     }
    26     int *next=getNext(target);
    27 
    28     int j=0; 
    29     for (int i=0;i<sizes;i++)
    30     {
    31         while(j>0&&source[i]!=target[j]) //j应该大于0,等于0的话前面没有子串也就不存在公共前后缀,不存在进入while循环的必要;
    32         {
    33             j=next[j]+1;
    34         }
    35         if (source[i]==target[j])
    36         {
    37             j++;
    38         }
    39         if (j==sizet)
    40         {
    41             return i-j+1;
    42             
    43         }
    44     }
    45     return -1;
    46     }
    47     
    48     int *getNext(const char *s)
    49 {
    50     int len=strlen(s);
    51     int *next=new int[len]; //存储最长公共前后缀长度减一,所以next[i]为前缀的最后一个元素的索引,next[i]+1为前缀后面第一个元素的索引;
    52     next[0]=-1;
    53     int k;
    54 
    55     for (int i=1;i<len;i++)
    56     {
    57         k=next[i-1];
    58         while(k>=0&&s[i]!=s[k+1])
    59         {
    60             k=next[k];
    61         }
    62         if (s[i]==s[k+1])
    63         {
    64             next[i]=next[i-1]+1;
    65         }
    66         else
    67         {
    68             next[i]=-1;
    69         }
    70     }
    71     
    72     return next;
    73 }
    74 };

     

     

  • 相关阅读:
    使用jquery.validate.js实现boostrap3的校验和验证
    MySQL 随机取数据效率问题
    qq在线客服代码
    使用Shell脚本查找程序对应的进程ID,并杀死进程
    Redis-概述
    JVM的类加载机制
    volatile
    java内存相关
    设计模式--模板方法
    设计模式概述
  • 原文地址:https://www.cnblogs.com/Tang-tangt/p/8658256.html
Copyright © 2011-2022 走看看