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,子串查找成员函数的定义:

 int String::indexOf(const char* s) const // 子串查找,返回下标
{
return kmp(m_str, s ? s : "");
} int String::indexOf(const String &s) const
{
return kmp(m_str, s.m_str);
}
 

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,删除指定字符串成员函数的定义:

 /* 删除下标 i 处长度为 len 的字符串 */
String& String::remove(int i, int len) // 和 insert() 返回的是相同的函数,还可以以字符串类继续访问,如查看删除后的字符串等
{
if( ( <= i ) && (i < m_length) )
{
int n = i;
int m = i + len; // 在 (n, m) 范围之内的字符都要删除掉 while( (n < m) && (m < m_length) ) // 删除的字符串长度是不能大于当前的长度的,否则没有意义
{
m_str[n++] = m_str[m++]; // 这个赋值很经典
} m_str[n] = '\0'; //这里为什么是 n,因为n是不断增加的,直到 m 为等于 length
m_length = n; // 不应该是 m_length - n 吗?
} return *this;
} String& String::remove(const char *s) // 删除子串
{
return remove(indexOf(s), s ? strlen(s) : );
} String& String::remove(const String &s) // 删除子串
{
return remove(indexOf(s), s.length());
}

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,减法操作符重载的定义:

 String String::operator - (const String& s) const  // 字符串自身会被改变
{
return String(*this).remove(s); // 直接调用构造函数产生一个新的临时字符串对象,值和当前字符串对象值相同,然后调用临时对象的remove() 函数将子串删除,最后将删除结果返回,但是当前的字符串没有被改变,因为是拷贝赋值
} String String::operator - (const char* s) const // 字符串自身会被改变
{
return String(*this).remove(s);
} String& String::operator -= (const String& s) // 字符串自生不会被改变
{
return remove(s);
} String& String::operator -= (const char* s)
{
return remove(s);
}

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,子串替换成员函数的定义:

 /* 用 s 替换字符串中的 t */
String& String::replace(const char* t, const char* s)
{
int index = indexOf(t); // 查找 t 的位置 if( index >= ) // t 存在于当前的字符串中
{
remove(t); // 不要复制粘贴代码,要复用
insert(index, s);
   } return *this;
} String& String::replace(const String& t, const char* s)
{
return replace(t.m_str, s);
} String& String::replace(const char* t, const String& s)
{
return replace(t, s.m_str);
} String& String::replace(const String& t, const String& s)
{
return replace(t.m_str, s.m_str);
}

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

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

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

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

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

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

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

 String String::sub(int i, int len) const  // 查找当前字符串中第 i 个位置长度为 len 的字符串
{
   String ret; if( ( <= i) && (i < m_length) )
{
if( len < ) len = ; // 当小于零时候,不可能,要归一化到 0
if(len+i > m_length) len = m_length - i; // 只能够提取这么长的长度 char* str = reinterpret_cast<char*>(malloc(len + )); if( str != NULL )
{
strncpy(str, m_str + i, len); // 从 m_str + i 位置拷贝 len 长度的字符串,这里 m_str 是字符串起始位置
} str[len] = '\0';
ret = str; // 返回子串 free(str);
}
else
{
THROW_EXCEPTION(IndexOutOfBoundsException, "Parameter i is invaid ...");
   } return ret;
}

7,本节课测试代码:

 #include <iostream>
#include "DTString.h"
#include "malloc.h"
#include <cstring> using namespace std;
using namespace DTLib; int main()
{
String s = "ababax";
   String s1 = s- "bax"; cout << s.str() << endl;
15   cout << s1.str() << endl; s -= "ba";
   s -= s;   cout << "[" << s.str() << "]" << endl; String s2 = "ababax";
   s2.replace("baba", "xyz");    cout << s2.str() << endl; String s3 = "ababax";
   String s4 = s3.sub(, );    cout << s4.str() << endl; return ;
}

8,小结:

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

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

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

1,当前字符串增加;

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

1,当前字符串删除;

3,查: indexOf,...

1,当前字符串查找;

4,改:replace,...

1,当前字符串更改;

字符串类——KMP算法的应用的更多相关文章

  1. 字符串类——KMP子串查找算法

    1, 如何在目标字符串 s 中,查找是否存在子串 p(本文代码已集成到字符串类——字符串类的创建(上)中,这里讲述KMP实现原理) ? 1,朴素算法: 2,朴素解法的问题: 1,问题:有时候右移一位是 ...

  2. [Algorithm] 字符串匹配算法——KMP算法

    1 字符串匹配 字符串匹配是计算机的基本任务之一. 字符串匹配是什么?举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串& ...

  3. 字符串匹配算法——KMP算法

    处理字符串的过程中,难免会遇到字符匹配的问题.常用的字符匹配方法 1. 朴素模式匹配算法(Brute-Force算法) 求子串位置的定位函数Index( S, T, pos). 模式匹配:子串的定位操 ...

  4. 查找字符串的 KMP 算法

    查找字符串是我们平常编程过程中经常遇到的,现在介绍一种查找字符串算法,增加程序的执行速度. 通常我们是这么写的: /* content: search a string in a othor stri ...

  5. 字符串匹配算法——KMP算法学习

    KMP算法是用来解决字符串的匹配问题的,即在字符串S中寻找字符串P.形式定义:假设存在长度为n的字符数组S[0...n-1],长度为m的字符数组P[0...m-1],是否存在i,使得SiSi+1... ...

  6. 字符串模式匹配KMP算法

    一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中 ...

  7. 字符串查找KMP算法(转)

    如果你用过ctrl+F这个快捷键,那么你有很大的概率使用过这个算法,这就是在待查找字符串(可能有成千上万个字符)中找出模式串(比较小,可能有几个字符),可能找到大于或者等于1次的位置.例如,在abab ...

  8. 字符串查找KMP算法

    如果你用过ctrl+F这个快捷键,那么你有很大的概率使用过这个算法,这就是在待查找字符串(可能有成千上万个字符)中找出模式串(比较小,可能有几个字符),可能找到大于或者等于1次的位置.例如,在abab ...

  9. c算法:字符串查找-KMP算法

    /* *用KMP算法实现字符串匹配搜索方法 *该程序实现的功能是搜索本目录下的所有文件的内容是否与给定的 *字符串匹配,如果匹配,则输出文件名:包含该字符串的行 *待搜索的目标串搜索指针移动位数 = ...

随机推荐

  1. .NET File 多图上传

    HTML代码: <div> <div> <input type="file" style="display:none" id=&q ...

  2. SQL SERVER将多行数据合并成一行

    1)比如表中有三列数据: 2)执行如下查询: SELECT [USER_NAME], [USER_ACCOUNT] , [ROLE_NAME] = stuff(( SELECT ',' + [ROLE ...

  3. python基础--4 元祖

    #元组,元素不可被修改,不能被增加或者删除 #tuple,有序 tu=(11,22,33,44,55,33) #count 获取指定元素在元祖中出现的次数 print(tu.count(33)) #i ...

  4. ln 硬链接与软链接

    1. 命令功能 ln 可以看做是link的简写,功能是创建链接文件,链接文件包括硬链接(hard link)和软链接(符号链接,symbolic link) 2. 语法格式 ln  [option]  ...

  5. Mongodb副本集实现及读写分离

    前言 地址:https://blog.csdn.net/majinggogogo/article/details/51586409 作者介绍了,mongodb副本集的读写原理,原理是通过代码层来实现. ...

  6. JS基础入门篇( 三 )—使用JS获取页面中某个元素的4种方法以及之间的差别( 一 )

    1.使用JS获取页面中某个元素的4种方法 1.通过id名获取元素 document.getElementById("id名"); 2.通过class名获取元素 document.g ...

  7. Java初步

    Java的核心优势:跨平台 Java SE:标准版Java EE:企业级Java ME:微型版 源文件(*.java)→编译器→字节码文件(*.class)→(类装载器→字节码校验器→解释器)[JRE ...

  8. python TypeError: must be str, not bytes错误

    TypeError: must be str, not bytes错误: 解答: 写文件处 f=open(filename, 'w')应该写为 open(filename, 'wb') 读文件时 f= ...

  9. Test 6.24 T3 水题

    问题描述 秋之国首都下了一场暴雨,由于秋之国地势高低起伏,不少地方出现了积水. 秋之国的首都可以看成一个 n 行 m 列的矩阵,第 i 行第 j 列的位置高度为 ai,j,首都以外的地方的高度可以都看 ...

  10. nginx配置虚拟主机-端口号区分/域名区分

    Nginx实现虚拟机 可以实现在同一台服务运行多个网站,而且网站之间互相不干扰.同一个服务器可能有一个ip,网站需要使用80端口.网站的域名不同. 区分不同的网站有三种方式:ip区分.端口区分.域名区 ...