zoukankan      html  css  js  c++  java
  • 【算法和数据结构】_8_线性结构_字符串_模式匹配_续_1

      其实,模式匹配的穷举法也可以改进,下面是经过改进后的代码。

    【Improve Version】

      其中StrMatchImp()函数是经过改进后的函数。

    /*
        本程序测试字符串的各种处理函数和操作
    */
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    //******************************************************0
    //            定义用户数据类型
    typedef long int LINT;
    typedef enum {FALSE,TRUE} BOOL;
    //******************************************************1
    
    
    
    
    //******************************************************0
    
    int StringMatch(char* String,char* subString,int StartIndex);
    int StringMatchRecall(char* String,char* subString,int StartIndex);
    int  StrMatchImp(char* string,char* subString,int startIndex);
    
    int main(int argc,char* argv[])
    {
        int x;
    
        x=StringMatch("abcdefghijklmn","lm",0);
            printf("%d \n",x);
    
        x=StringMatchRecall("abcdefghijklmn","x",0);
            printf("%d \n",x);
    
        x=StrMatchImp("abcdefghijklmn","lm",0);
            printf("%d \n",x);
    
        getchar();
        getchar();
        return 0;
    }
    //******************************************************1
    
    
    
    
    
    //******************************************************0
    /*
    函数功能:
        模式匹配朴素算法:双循环
    函数原型:
        int StringMatch(char* String,char* subString,int StartIndex)
    函数参数:
        char* String:字符串
        char* subString:模式字符串
        int StartIndex:搜索开始索引
    返回值:
        如果匹配成功,则返回模式字符串在字符串中开始的首地址;
        如果匹配失败,则返回-1
    异常:
        无
    */
    int StringMatch(char* String,char* subString,int StartIndex)
    {
        int i,
            j;
    
        int StrLen,
            SubStrLen;
    
        StrLen=strlen(String);
        SubStrLen=strlen(subString);
    
        //检查指针有效性和空串
        //其实这里也可以不检测  StartIndex>strlen(String)-strlen(subString)
        if( !String || !subString || !String[0] || !subString\
            || StartIndex > StrLen-SubStrLen\
          )
            return -1;
    
        for(i=StartIndex;i<= StrLen - SubStrLen ;i++)
        {
            for(j=0; j < SubStrLen ;j++)
            {
                if(String[i+j] - subString[j])
                    break;
            }
            if(j==SubStrLen)  //这么判断因为要结束循环正好相等
                return ++i;  //这个地方不能用i++
        }
    
        return -1;
    }
    //******************************************************1
    
    
    
    
    
    //******************************************************0
    /*
    函数功能:
        模式匹配朴素算法:单循环回溯
    函数原型:
        int StringMatchRecall(char* String,char* subString,LINT StartIndex)
    函数参数:
        char* String:字符串
        char* subString:模式字符串
        int StartIndex:搜索开始索引
    返回值:
        如果匹配成功,则返回模式字符串在字符串中开始的首地址;
        如果匹配失败,则返回-1
    异常:
        无
    */
    int StringMatchRecall(char* String,char* subString,int StartIndex)
    {
        int i,
            j;
    
        int StrLen,
            SubStrLen;
    
        StrLen=strlen(String);
        SubStrLen=strlen(subString);
    
        //检查指针有效性和空串
        //其实这里也可以不检测  StartIndex>strlen(String)-strlen(subString)
        if( !String || !subString || !String[0] || !subString\
            || StartIndex > StrLen-SubStrLen\
          )  return -1;
    
        i=StartIndex;
        j=0;
    
        while( i < StrLen  )
        {
            if(String[i] == subString[j] )
            {
                ++j;
                ++i;
                 
            }
            else
            {
                i=i-j+1;  //回溯
                j=0;
            }
            if(j==SubStrLen)
                return i-j+1;
        }
        return -1;
    }
    //******************************************************1
    
    
    
    
    
    
    
    //******************************************************0
    /*
    函数功能:
        字符串模式匹配穷举法:改进版
    函数原型:
        int  StrMatchImp(char* string,char* subString,int startIndex)
    函数参数:
        char* string: 字符串
        char* subString:模式字符串
        int startIndex:搜索首索引
    返回值:
        如果匹配成功,返回匹配首字符的index+1
    异常:
        无
    */
    int  StrMatchImp(char* string,char* subString,int startIndex)
    {
         int i,
            j;
    
        int StrLen,
            SubStrLen;
    
        StrLen=strlen(string);
        SubStrLen=strlen(subString);
    
        //检查指针有效性和空串
        //其实这里也可以不检测  StartIndex>strlen(String)-strlen(subString)
        if( !string || !subString || !string[0] || !subString\
            || startIndex > StrLen-SubStrLen\
          )
            return -1;
    
        for(i=startIndex;i<= StrLen - SubStrLen ;i++)
        {
            for(j=0; j < SubStrLen ;j++)
            {
                if( string[i+j] - subString[j])
                    break;
                else
                {   
                    //如果模式的首字符subString[0]已经匹配,
                    //则判断最后一个字符subString[SubStrLen-1]是否匹配
                    //依次类推,这样最好的时候可以提高效率,
                    //最差的时候还是需要O(m*n) 
                    if(string[i+SubStrLen-1-j] - subString[SubStrLen-1-j])
                        break;
                }
            }
            if(j==SubStrLen)  //这么判断因为要结束循环正好相等,也可用subString[j]=='\0'
                return ++i;  //这个地方不能用i++
        }
    
        return -1;
    }
    
    //******************************************************1
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    //******************************************************0
    /*
    函数功能:
        求解字符串本身的从尾节点往头节点方向子串中最大的匹配串
    函数原型:
        int GetMaxSubStringLen(const char* string)
    函数参数:
        const char* String:字符串
    返回值:
        如果有的话则返回最大长度,否则就返回-1
    异常:
        无
    */
    int GetMaxSubStringLen(const char* string)
    {
        return -1;
    }
    //******************************************************1

      程序运行结果如下所示:

      

      这个东西还是有很复杂啊,哎,需要继续学习学习。

  • 相关阅读:
    HTTP压力测试工具apache的ab的使用方法
    [转]Memcached 协议中英文对照
    [转]Windows下删除.svn文件夹的最简易方法
    [转]50 个便利的 Web 设计工具
    Navicat数据存放位置和备份数据库路径设置
    Silverlight第三方控件
    MVC3.0中使用JQuery.DataTable插件。
    什么是句柄?为什么会有句柄?HANDLE
    WPF内存释放
    ArcGis for wpf 符号渲染
  • 原文地址:https://www.cnblogs.com/volcanol/p/3044490.html
Copyright © 2011-2022 走看看