字符串类——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算法实现字符串匹配搜索方法 *该程序实现的功能是搜索本目录下的所有文件的内容是否与给定的 *字符串匹配,如果匹配,则输出文件名:包含该字符串的行 *待搜索的目标串搜索指针移动位数 = ...
随机推荐
- tf.clip_by_global_norm
首先明白这个事干嘛的,在我们做求导的时候,会遇到一种情况,求导函数突然变得特别陡峭,是不是意味着下一步的进行会远远高于正常值,这个函数的意义在于,在突然变得陡峭的求导函数中,加上一些判定,如果过于陡峭 ...
- 字符串format函数使用
#format拼接字符串,format()内的参数必须为可迭代的对象p1="i am {2},age {1},{0}".format("seven",18,'a ...
- POJ 2104 区间第k大(主席树)
题目链接:http://poj.org/problem?id=2104 题目大意:给定还有n个数的序列,m个操作,每个操作含有l,r,k,求区间[l,r]第k大 解题思路:线段树只能维护序列的最大值最 ...
- git@github.com出现Permission denied (publickey)
上传项目的时候出现Permission denied (publickey)这个问题 解决方案如下: 看本地的.git/config设置的仓库url地址和github使用的链接地址是否一致如下图,如u ...
- redis 并发测试安全测试代码
package com.jd.ng.shiro.controller; import org.slf4j.Logger;import org.slf4j.LoggerFactory;import or ...
- UVa 10054 : The Necklace 【欧拉回路】
题目链接 题目大意:我的妹妹有一串由各种颜色组成的项链. 项链中两个连续珠子的接头处共享同一个颜色. 如上图, 第一个珠子是green+red, 那么接这个珠子的必须以red开头,如图的red+whi ...
- python学习笔记(十九)面向对象编程,类
一.面向对象编程 面向对象,是一种程序设计思想. 编程范式:编程范式就是你按照什么方式去编程,去实现一个功能.不同的编程范式本质上代表对各种类型的任务采取的不同的解决问题的思路,两种最重要的编程范式分 ...
- 批处理bat文件显示中文乱码解决方式
1.下载Notepad++并安装 2.选择编码,将文件编码转换为ANSI编码
- U盘安装win8(win7)+centos7双系统
centos7除了之后,就像尝鲜看看,但是发现安装之后会失去win8启动项.导致重装系统,经过反复折腾,终于搞定了,发出来共享下.默认你的 window系统已经安装好,不介绍window安装过程.本文 ...
- JAVA WEB怎么实现大文件上传
javaweb上传文件 上传文件的jsp中的部分 上传文件同样可以使用form表单向后端发请求,也可以使用 ajax向后端发请求 1.通过form表单向后端发送请求 改进后的代码不需要form标签,直 ...