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. How to compile and install Linux Kernel 5.1.2 from source code

    How to compile and install Linux Kernel 5.1.2 from source code Compiling a custom kernel has its adv ...

  2. python3 使用 django-xadmin 遇到的许多坑

    几乎所有公司项目都是python2的, xadmin对Python2 很友好,对Python3 很不友好, 所以在Python3 环境下使用xadmin遇到了许多意想不到的坑,在这里记录并分享一下: ...

  3. 继承和构造函数语法造成的一个bug

    一 出错误的代码 开发环境: visual studio 2017 社区版 #include "pch.h" #include <iostream> #include ...

  4. php7 mysqli_query返回1 , 但是更新失败

    HTML中忘了传id 

  5. 【leetcode】1054. Distant Barcodes

    题目如下: In a warehouse, there is a row of barcodes, where the i-th barcode is barcodes[i]. Rearrange t ...

  6. vue兄弟组件之前传信

    1.使用vuex 2.子传父,父传子 3.使用中央事件总线 1.新建一个js文件,然后引入vue 实例化vue 最后暴露这个实例 2.在要用的组件内引入这个组件 3.通过vueEmit.$emit(' ...

  7. sqlserver备份和恢复-5

    视图备份和恢复 备份 1. 2. 恢复 1. 2. 3.勾选覆盖现有数据库. 4. bat备份恢复 原文: https://www.cnblogs.com/lonelyxmas/p/7958649.h ...

  8. vue动态路由传值以及get传值及编程式导航

    1.动态路由传值 1.配置路由处 { path: '/content/:id', component: Content }, // 动态路由 2.对应页面传值 <router-link :to= ...

  9. scau 1079 三角形(暴力)

    </pre>1079 三角形</h1></center><p align="center" style="margin-top: ...

  10. Java连接MySql数据库之JDBC

    1.首先创建一个java Project项目 2.起一个英文的项目名 3.此窗口点击NO 4.此时项目状态如下 5.创建一个文件夹,并将mysql-connector-java-5.1.8-bin.j ...