zoukankan      html  css  js  c++  java
  • 字符串类——KMP算法的应用

    1,字符串类中的新功能(本文代码已集成到字符串类——字符串类的创建(上)中,这里讲述函数实现原理):

     

          

    2,子串查找(KMP 算法直接运用):

           1,int indexOf(const char* s) const;

           2,int indexOf(const String& s) const;

           3,子串查找成员函数的声明:

        int indexOf(const char* ) const;
        int indexOf(const String& s) const;

      4,子串查找成员函数的定义:

    1 int String::indexOf(const char* s) const // 子串查找,返回下标
    2 {
    3     return kmp(m_str, s ? s : "");
    4 }
    5 
    6 int String::indexOf(const String &s) const
    7 {
    8     return kmp(m_str, s.m_str);
    9 }
     

    3,在字符串中将指定的子串删除:

           1,String& remove(const char* s);

           2,String& remove(const String& s);

                  1,根据 kmp 在目标字符串中查找子串的位置;

                  2,通过子串位置和子串长度进行删除;

         3,删除指定字符串成员函数的声明:

         String& remove(int i, int len);
         String& remove(const char* s);
         String& remove(const String& s);

      4,删除指定字符串成员函数的定义:

     1 /* 删除下标 i 处长度为 len 的字符串 */
     2 String& String::remove(int i, int len)   // 和 insert() 返回的是相同的函数,还可以以字符串类继续访问,如查看删除后的字符串等
     3 {
     4     if( (0 <= i ) && (i < m_length) )
     5     {
     6         int n = i;
     7         int m = i + len; // 在 (n, m) 范围之内的字符都要删除掉
     8 
     9         while( (n < m) && (m < m_length) ) // 删除的字符串长度是不能大于当前的长度的,否则没有意义
    10         {
    11             m_str[n++] = m_str[m++];   // 这个赋值很经典
    12         }
    13 
    14         m_str[n] = ''; //这里为什么是 n,因为n是不断增加的,直到 m 为等于 length
    15         m_length = n;  // 不应该是 m_length - n 吗?
    16 }
    17 
    18     return *this;
    19 }
    20 
    21 String& String::remove(const char *s) // 删除子串
    22 {
    23     return remove(indexOf(s), s ? strlen(s) : 0);  
    24 }
    25 
    26 String& String::remove(const String &s) // 删除子串
    27 {
    28     return remove(indexOf(s), s.length());
    29 }

                 

    4,字符串的减法操作定义(operator - ):

           1,使用 remove 实现字符串间的减法操作;

                  1,字符串自身不被修改;

                  2,返回产生的新串;

     

      2,减法操作符重载的声明:

        String operator - (const String& s) const;
        String operator - (const char* s) const;
        String& operator -= (const String& s); 
        String& operator -= (const char* s);

      3,减法操作符重载的定义:

     1 String String::operator - (const String& s) const  // 字符串自身会被改变
     2 {
     3     return String(*this).remove(s);  // 直接调用构造函数产生一个新的临时字符串对象,值和当前字符串对象值相同,然后调用临时对象的remove() 函数将子串删除,最后将删除结果返回,但是当前的字符串没有被改变,因为是拷贝赋值
     4 }
     5 
     6 String String::operator - (const char* s) const  // 字符串自身会被改变
     7 {
     8     return String(*this).remove(s);  
     9 }
    10 
    11 String& String::operator -= (const String& s) // 字符串自生不会被改变
    12 {
    13     return remove(s);
    14 }
    15 
    16 String& String::operator -= (const char* s)
    17 {
    18     return remove(s);
    19 }

    5,字符串中的子串替换:

           1,String& replace(const char* t, const char* s);

           2,String& replace(const String& t, const char* s);

           3,String& replace(cosnt char* t, const String& s);

           4,String& replace(const String& t, const String& s);

      5,子串替换成员函数的声明:

        String& replace(const char* t, const char* s);
        String& replace(const String& t, const char* s);
        String& replace(const char* t, const String& s);
        String& replace(const String& t, const String& s);

      6,子串替换成员函数的定义:

     1 /* 用 s 替换字符串中的 t */
     2 String& String::replace(const char* t, const char* s)
     3 {
     4     int index = indexOf(t); // 查找 t 的位置
     5 
     6     if( index >= 0 ) // t 存在于当前的字符串中
     7     {
     8         remove(t);  // 不要复制粘贴代码,要复用
     9         insert(index, s);
    10    }
    11 
    12     return *this;
    13 }
    14 
    15 String& String::replace(const String& t, const char* s)
    16 {
    17     return replace(t.m_str, s);
    18 }
    19 
    20 String& String::replace(const char* t, const String& s)
    21 {
    22     return replace(t, s.m_str);
    23 }
    24 
    25 String& String::replace(const String& t, const String& s)
    26 {
    27     return replace(t.m_str, s.m_str);
    28 }

    6,从字符串中创建子串:

           1,String sub(int i, int len) const;

                  1,以 i 为起点去长度为 len 的子串;

                  2,子串提取不会改变字符串本身的状态;

     

      2,从字符串中创建子串成员函数的声明:

        String sub(int i, int len) const; // 因为这里不会改变当前字符串状态,所以为 const 成员函数;

      3,从字符串中创建子串成员函数的定义:

     1 String String::sub(int i, int len) const  // 查找当前字符串中第 i 个位置长度为 len 的字符串
     2 {
     3    String ret;
     4 
     5     if( (0 <= i) && (i < m_length) )
     6     {
     7         if( len < 0 ) len = 0; // 当小于零时候,不可能,要归一化到 0
     8         if(len+i > m_length) len = m_length - i; // 只能够提取这么长的长度
     9 
    10         char* str = reinterpret_cast<char*>(malloc(len + 1));
    11 
    12         if( str != NULL )
    13         {
    14             strncpy(str, m_str + i, len); // 从 m_str + i 位置拷贝 len 长度的字符串,这里 m_str 是字符串起始位置
    15         }
    16 
    17         str[len] = '';
    18         ret = str;  // 返回子串
    19 
    20         free(str);
    21     }
    22     else
    23     {
    24         THROW_EXCEPTION(IndexOutOfBoundsException, "Parameter i is invaid ...");
    25    }
    26 
    27     return ret;
    28 }

    7,本节课测试代码:

     1 #include <iostream>
     2 #include "DTString.h"
     3 #include "malloc.h"
     4 #include <cstring>
     5 
     6 using namespace std;
     7 using namespace DTLib;
     8 
     9 int main()
    10 {
    11     String s = "ababax";
    12    String s1 = s- "bax";
    13 
    14     cout << s.str() << endl;
    15    cout << s1.str() << endl;
    16 
    17     s -= "ba";
    18    s -= s;
    19 
    20    cout << "[" << s.str() << "]" << endl;
    21 
    22     String s2 = "ababax";
    23    s2.replace("baba", "xyz");
    24 
    25    cout << s2.str() << endl;
    26 
    27     String s3 = "ababax";
    28    String s4 = s3.sub(3, 2);
    29 
    30    cout << s4.str() << endl;
    31 
    32     return 0;
    33 }

                 

    8,小结:

           1,字符串类是工程开发中必不可少的组件;

           2,字符串中应该包含常用字符串操作函数:

                  1,增:insert,operator +,...;

                         1,当前字符串增加;

                  2,删:remove,operator -,...;

                         1,当前字符串删除;

                  3,查: indexOf,...

                         1,当前字符串查找;

                  4,改:replace,...

                         1,当前字符串更改;

  • 相关阅读:
    原型模式
    浅复制和深复制
    适配器模式
    外观模式
    模板方法
    建造者模式
    代理模式
    Centos7重新安装yum
    关于mongodb创建索引的一些经验总结(转)
    MongoDB查询语句(转)
  • 原文地址:https://www.cnblogs.com/dishengAndziyu/p/10923733.html
Copyright © 2011-2022 走看看