字符串类——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,子串查找成员函数的定义:
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算法的应用的更多相关文章
- 字符串类——KMP子串查找算法
1, 如何在目标字符串 s 中,查找是否存在子串 p(本文代码已集成到字符串类——字符串类的创建(上)中,这里讲述KMP实现原理) ? 1,朴素算法: 2,朴素解法的问题: 1,问题:有时候右移一位是 ...
- [Algorithm] 字符串匹配算法——KMP算法
1 字符串匹配 字符串匹配是计算机的基本任务之一. 字符串匹配是什么?举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串& ...
- 字符串匹配算法——KMP算法
处理字符串的过程中,难免会遇到字符匹配的问题.常用的字符匹配方法 1. 朴素模式匹配算法(Brute-Force算法) 求子串位置的定位函数Index( S, T, pos). 模式匹配:子串的定位操 ...
- 查找字符串的 KMP 算法
查找字符串是我们平常编程过程中经常遇到的,现在介绍一种查找字符串算法,增加程序的执行速度. 通常我们是这么写的: /* content: search a string in a othor stri ...
- 字符串匹配算法——KMP算法学习
KMP算法是用来解决字符串的匹配问题的,即在字符串S中寻找字符串P.形式定义:假设存在长度为n的字符数组S[0...n-1],长度为m的字符数组P[0...m-1],是否存在i,使得SiSi+1... ...
- 字符串模式匹配KMP算法
一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中 ...
- 字符串查找KMP算法(转)
如果你用过ctrl+F这个快捷键,那么你有很大的概率使用过这个算法,这就是在待查找字符串(可能有成千上万个字符)中找出模式串(比较小,可能有几个字符),可能找到大于或者等于1次的位置.例如,在abab ...
- 字符串查找KMP算法
如果你用过ctrl+F这个快捷键,那么你有很大的概率使用过这个算法,这就是在待查找字符串(可能有成千上万个字符)中找出模式串(比较小,可能有几个字符),可能找到大于或者等于1次的位置.例如,在abab ...
- c算法:字符串查找-KMP算法
/* *用KMP算法实现字符串匹配搜索方法 *该程序实现的功能是搜索本目录下的所有文件的内容是否与给定的 *字符串匹配,如果匹配,则输出文件名:包含该字符串的行 *待搜索的目标串搜索指针移动位数 = ...
随机推荐
- 【记录】mybatis mapper.xml 基础
<choose> <when test=""> //... </when> <otherwise> //... </other ...
- shell 搜索指定目录下所有 jar 文件生成csv文件
虽说比较简单,但希望分享给大家.按需求改成想找的:例如txt,xls 等. 脚本名 扫描的路径 文件名 testFind.sh / testFind.txt (如果未配置环境变量 ./testFi ...
- 洛谷 P2783 有机化学之神偶尔会做作弊(Tarjan,LCA)
题目背景 LS中学化学竞赛组教练是一个酷爱炉石的人. 有一天他一边搓炉石一边监考,而你作为一个信息竞赛的大神也来凑热闹. 然而你的化竞基友却向你求助了. “第1354题怎么做”<--手语 他问道 ...
- 00.斐波那契数列第n项
# 斐波那契数列第n项 # 1 1 2 3 5 8 def fib(n): if n <= 2: return 1 else: return fib(n-2)+fib(n-1) def fib2 ...
- bui拍照上传、相册上传注意事项
1.控制台输入 bui.currentPlatform 可查看工程项目基于什么平台 如:bingotouch 2.如果是 bingotouch , 在 index.js 或者其它配置的地方, 加上 ...
- [洛谷P4841][集训队作业2013]城市规划
传送门 题目大意 求出\(n\)个点的简单(无重边无自环)有标号无向连通图数目.\(n\leq 130000\). 题解 题意非常简单,但做起来很难.这是道生成函数经典题,博主当做例题学习用的.博主看 ...
- 当 Messaging 遇上 Jepsen
分布式系统面临的挑战 Is it better to be alive and wrong or right and dead? 随着计算机技术的发展,系统架构从集中式演进到分布式.分布式系统相对于单 ...
- CSS/CSS3常用的样式
强制文本显示 让一段文字在固定宽度在一行显示,最后一个字符为省略标记(...),css样式如下 单行显示语法:white-space:nowrap; div{ white-space:nowrap; ...
- 20180805-Java 异常处理
try{ //程序代码}catch(ExceptionName e1){ //Catch 块} 下面的例子中声明有两个元素的一个数组,当代码试图访问数组的第三个元素的时候就会抛出一个异常. //文件名 ...
- BUUCTF | [CISCN2019 华北赛区 Day1 Web2]ikun
步骤: 找到lv6的购买出,修改折扣买lv6 :然后找到admin的登陆界面,JWT破解,登陆admin :点击一键成为大会员,利用python反序列化漏洞读取flag 解析: 这题师傅们的WP已经很 ...