字符串类——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算法实现字符串匹配搜索方法 *该程序实现的功能是搜索本目录下的所有文件的内容是否与给定的 *字符串匹配,如果匹配,则输出文件名:包含该字符串的行 *待搜索的目标串搜索指针移动位数 = ...
随机推荐
- .NET File 多图上传
HTML代码: <div> <div> <input type="file" style="display:none" id=&q ...
- SQL SERVER将多行数据合并成一行
1)比如表中有三列数据: 2)执行如下查询: SELECT [USER_NAME], [USER_ACCOUNT] , [ROLE_NAME] = stuff(( SELECT ',' + [ROLE ...
- python基础--4 元祖
#元组,元素不可被修改,不能被增加或者删除 #tuple,有序 tu=(11,22,33,44,55,33) #count 获取指定元素在元祖中出现的次数 print(tu.count(33)) #i ...
- ln 硬链接与软链接
1. 命令功能 ln 可以看做是link的简写,功能是创建链接文件,链接文件包括硬链接(hard link)和软链接(符号链接,symbolic link) 2. 语法格式 ln [option] ...
- Mongodb副本集实现及读写分离
前言 地址:https://blog.csdn.net/majinggogogo/article/details/51586409 作者介绍了,mongodb副本集的读写原理,原理是通过代码层来实现. ...
- JS基础入门篇( 三 )—使用JS获取页面中某个元素的4种方法以及之间的差别( 一 )
1.使用JS获取页面中某个元素的4种方法 1.通过id名获取元素 document.getElementById("id名"); 2.通过class名获取元素 document.g ...
- Java初步
Java的核心优势:跨平台 Java SE:标准版Java EE:企业级Java ME:微型版 源文件(*.java)→编译器→字节码文件(*.class)→(类装载器→字节码校验器→解释器)[JRE ...
- python TypeError: must be str, not bytes错误
TypeError: must be str, not bytes错误: 解答: 写文件处 f=open(filename, 'w')应该写为 open(filename, 'wb') 读文件时 f= ...
- Test 6.24 T3 水题
问题描述 秋之国首都下了一场暴雨,由于秋之国地势高低起伏,不少地方出现了积水. 秋之国的首都可以看成一个 n 行 m 列的矩阵,第 i 行第 j 列的位置高度为 ai,j,首都以外的地方的高度可以都看 ...
- nginx配置虚拟主机-端口号区分/域名区分
Nginx实现虚拟机 可以实现在同一台服务运行多个网站,而且网站之间互相不干扰.同一个服务器可能有一个ip,网站需要使用80端口.网站的域名不同. 区分不同的网站有三种方式:ip区分.端口区分.域名区 ...