算法-朴素字符串匹配

字符串匹配

http://www.cnblogs.com/jingmoxukong/p/4343770.html

模式匹配是数据结构中字符串的一种基本运算,给定一个子串,要求在某个字符串中找出与该子串相同的所有子串,这就是模式匹配

假设P是给定的子串,T是待查找的字符串,要求从T中找出与P相同的所有子串,这个问题成为模式匹配问题。P称为模式,T称为目标。如果T中存在一个或多个模式为P的子串,就给出该子串在T中的位置,称为匹配成功;否则匹配失败。

朴素字符串匹配

http://www.cnblogs.com/jingmoxukong/p/4343770.html

BF算法的算法思想是:

目标串T的的第一个字符起与模式串P的第一个字符比较。

若相等,则继续对字符进行后续的比较;否则目标串从第二个字符起与模式串的第一个字符重新比较。

直至模式串中的每个字符依次和目标串中的一个连续的字符序列相等为止,此时称为匹配成功,否则匹配失败。

C代码实现

一般这种算法的实现中, 总是会出现四个元素, 模式串, 目标串, 模式串的比较下标 i, 目标串的比较下标 j

再加上返回值下标 ,

算法中出现的元素太多, 不易理解。

下面c版本, 按照功能拆分算法为两个函数,

1、算法接口对应的函数为主函数, 负责每次比较的目标串的起始位置控制,

2、 另外一个函数, 负责比较功能, 计算模式串是否为 另一字符串的头部, 此函数为主函数调用。

实现精神指导: 功能拆分,编码层面的分治策略, 以更好控制代码复杂度(例如嵌套、 循环、 元素数目、 以及语义性), 便于读者理解, 便于提供高质量的代码。

https://github.com/fanqingsong/code-snippet/blob/master/C/naive_string_matcher/naive_string_matcher.c

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <malloc.h>
#include <stdarg.h>
#include <ctype.h>


typedef enum returnType {
    FAIL = 0,
    SUCCESS,
} E_RETURN_TYPE;
    
typedef enum boolType {
    FALSE = 0,
    TRUE,
} E_BOOL_TYPE;


/* ------------------------------ common function --------------------------------- */
// MyPrintf == puts + format args
void MyPrintf(char* fmt, ...)
{
    MyVaPrintf(fmt);
    //system("pause");
}


E_BOOL_TYPE string_is_head_of_string(char* headStr, char* string)
{
    char* pHeadStr = NULL;
    char* pString = NULL;
    char chHead = 0;
    char chString = 0;

    if (!headStr || !string)
    {
        MyPrintf("arg is null");
        return FALSE;
    }

    pHeadStr = headStr;
    pString = string;

    while( TRUE )
    {
        chHead = *pHeadStr;
        chString = *pString;

        // headStr is over, now result is true
        if ( chHead == 0 )
        {
            return TRUE;
        }

        // string is over firstly, return false 
        if ( chString == 0 )
        {
            return FALSE;
        }

        // headStr is not a head of string
        if ( chHead != chString )
        {
            return FALSE;
        }

        pHeadStr++;
        pString++;
    }
}

int naive_matcher(char* string, char* substr)
{
    char* cursor = NULL;
    int index = 0;
    int subLen = 0;
    int stringLen = 0;
    int maxPos = 0;

    if (!string || !substr)
    {
        MyPrintf("arg is null");
    }

    subLen = strlen(substr);
    stringLen = strlen(string);
    maxPos = stringLen - subLen + 1;

    while ( index < maxPos )
    {
        cursor = string + index;
        if ( string_is_head_of_string(substr, cursor) )
        {
            return index;
        }
        
        index++;
    }

    return -1;
}

int main(void)
{
    char string[] = "i love you";
    char substr[] = "love";
    int index = -1;

    index = naive_matcher(string, substr);

    if ( -1 == index )
    {
        MyPrintf("substr(%s) is not in string(%s)", substr, string);
    }
    else
    {
        MyPrintf("substr(%s) is at index(%d) of string(%s)", substr, index, string);
    }
    
    return 0; 
}
原文地址:https://www.cnblogs.com/lightsong/p/4937716.html