一个精简的string类
来源:互联网 发布:linux 命令行修改权限 编辑:程序博客网 时间:2024/05/14 14:28
今天在看数据结构的时候发现一个String类的ADT表示以及实现让人看着很不舒服,于是乎愚蠢的自己实现了一个String类,这个类的接口功能和标准库中的string类是一致的,由于里面的字串操作函数都是自己实现的,所以效率一定很低,(标准库中的字串操作函数是汇编实现的J~~~),经过简单的测试,my String似乎已经正确实现,由于只实现了标准的string的一般的操作,并没有实现迭代操作,所以只能将String类称作“一个精简的,但是异常低效的stringJ”,好了,不说了,看代码吧,有错误大家请热烈的扔鸡蛋 J.
1:类中有些地方使用了“自动构造类型转换”,所以实现的功能还是比较多的。
2:使用了库函数memcpy来实现数据的移动,这样做似乎比循环移动数据要高效
3:实现了字符串模式匹配的KMP算法
※ 文件String.h
#ifndef STRING_H_
#define STRING_H_
#include <iostream>
#ifndef NOPOS
#define NOPOS -0
#endif
//size_t : long unsigned int
class String {
public:
String();
String( const char* ch ); //由字符数组构造
String( const String& str);
virtual ~String();
String& Append(const String& s );
//在当前串追加一个字符串
inline size_t Size() const { return m_iLength;}
//当前字符串长度
const char* c_str() const;
//返回当前串的一个拷贝
int Compare( const String& s, size_t n) const ;
//将当前串从n位置与S进行比较,如果比较部分相同,返回0,
//如果相同部分在N前返回-1,如果在N后,则返回1
const char* Data() const;
//返回串中的内容
String& Erase( size_t n, size_t m);
//删除自串中n到m之间的字符
size_t Find(const String& s, size_t n=0);
//从n位置开始,搜索字串s如果搜到,则返回首次出现该字串的位置,
//如果没有,返回常数NOPOS
String& Insert(size_t n, const String& s);
//在n位置出插入字串s
const char* operator[] (size_t i) const;
char* operator[](size_t i);
//返回索引i处字符的地址
int rFind(const String& s, int n=NOPOS);
//反向搜索字串s
String& operator=(const String& str);
//friend function
friend std::istream& operator>>(std::istream& sin, String& s);
friend std::ostream& operator<<(std::ostream& sout, String& s);
friend String operator+( const String& s1, const String& s2);
friend bool operator== ( const String& s1, const String& s2);
friend bool operator!= ( const String& s1, const String& s2);
friend bool operator>( const String& s1, const String& s2);
friend bool operator>=( const String& s1, const String& s2);
friend bool operator<( const String& s1, const String& s2);
friend bool operator<=( const String& s1, const String& s2);
protected:
//reimplement cstring functions
char* strcat(char *t, const char *s);
size_t strlen( const char *s) const;
char* strcpy( char *t, const char *s);
int strcmp(const char*t, const char*s, size_t n) const;
char* strinsert(size_t n, char **dstr, const char *sstr);
void fail(int *fail, const char* ch); //给失效匹配数组赋值的函数
private:
char* cstr;
size_t m_iLength;
};
#endif /*STRING_H_*/
※ ※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
※文件String.cpp
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
#include "String.h"
#include <memory.h>
#include <iostream>
String::String()
{
cstr = new char[1];
*cstr = '/n'; //新建空的字串
m_iLength= 0;
}
String::String(const char* ch )
{
m_iLength = strlen(ch);
cstr = new char[m_iLength+1];
strcpy(cstr, ch); //拷贝字符串,包括'/0'
}
String::String( const String& str)
{
m_iLength = str.m_iLength;
cstr = new char[m_iLength+1];
strcpy(cstr, str.cstr);
}
String::~String()
{
delete[] cstr;
}
String& String::Append(const String& s)
{
char *ch ;
if(s.m_iLength>0)
{
ch = new char[m_iLength+s.m_iLength+1];
memcpy(ch, cstr, m_iLength+1);
strcat(ch, s.cstr);
m_iLength = strlen(ch);
delete[] cstr;
cstr = ch;
}
return *this;
}
const char* String::c_str() const
{
return cstr;
}
int String::Compare(const String& s, size_t n) const
{
return strcmp(cstr, s.cstr, n);
}
const char* String::Data() const
{
return cstr;
}
String& String::Erase( size_t n, size_t m)
{
if(m==0) return *this;
if((n+m) > m_iLength) m = m_iLength - n;
char* str2 = new char[m_iLength-m+1];
//拷贝内存区
memcpy(str2, cstr, n);
memcpy(str2+n, cstr+n+m, m_iLength-m+1);
delete[] cstr;
cstr = str2;
m_iLength -= m; //重设字串长度;
return *this;
}
String& String::Insert( size_t n, const String& s)
{
strinsert(n, &cstr, s.cstr);//&cstr 显然,这里要改变cstr 指针
m_iLength = strlen(cstr);
return *this;
}
String& String::operator=(const String& str)
{
m_iLength = str.m_iLength;
cstr = new char[m_iLength+1];
strcpy(cstr, str.cstr);
return *this;
}
const char* String::operator[] (size_t i) const
{
if(i<0) i=0;
if(i>m_iLength+1) i=m_iLength+1;
return cstr+i;
}
char* String::operator[](size_t i)
{
if(i<0) i=0;
if(i>m_iLength+1) i=m_iLength+1;
return cstr+i;
}
String operator+( const String& s1, const String& s2)
{
String ts1(s1);
return ts1.Append(s2);
}
bool operator== ( const String& s1, const String& s2)
{
if( s1.Size() != s2.Size()) return false;
if(!s1.Compare(s2,s2.Size())) return true; //利用字符比较
return false;
}
bool operator!= ( const String& s1, const String& s2)
{
return !operator==(s1, s2);
}
bool operator>( const String& s1, const String& s2)
{
return (s1.Compare(s2,s2.Size()) >0);
}
bool operator>=( const String& s1, const String& s2)
{
return (s1.Compare(s2,s2.Size()) >0 || s1.Compare(s2,s2.Size()) == 0);
}
bool operator<( const String& s1, const String& s2)
{
return (s1.Compare(s2,s2.Size()) < 0);
}
bool operator<=( const String& s1, const String& s2)
{
return (s1.Compare(s2,s2.Size()) < 0 || s1.Compare(s2,s2.Size()) == 0);
}
std::istream& operator>>(std::istream& sin, String& s)
{
char* ch;
sin >> ch;
s = ch;
return sin;
}
std::ostream& operator<<(std::ostream& sout, String& s)
{
sout << s.cstr;
return sout;
}
//----------------------------------------------------
//Protected function defines
//练手,愚蠢的再次实现几个字符串操作函数
//以后再也不能干这样的蠢事!!!!!!!!!
//----------------------------------------------------
size_t String::strlen( const char *s) const
{
if(s == NULL) return 0;
const char* p = s;
size_t size = 0;
while(*p++)
{
size++;
}
return size;
}
char* String::strcpy( char *t, const char *s)
{
if(t!=NULL && s!=NULL)
{
char* tmptr1 = t;
const char* tmptr2 = s;
while((*tmptr1++ = *tmptr2++) != '/0');
}
return t;
}
char* String::strcat(char *t, const char *s)
{
if( t==NULL && s==NULL ) return t;
char* tmptr1 = t;
const char* tmptr2 = s;
while((*tmptr1)) tmptr1++;
while((*tmptr1++ = *tmptr2++) != '/0');
return t;
}
int String::strcmp(const char *t, const char *s, size_t n) const
{
size_t len1 = strlen(t);
size_t len2 = strlen(s);
if(len1 < len2)
{
n = len1;
}
else
{
n = len2;
}
int cmpresult = 0; //字典序比较结果
const char* tmpch1 = t;
const char* tmpch2 = s;
size_t i = 0;
while( (*tmpch1 == *tmpch2) && i<n )
{
i++;
tmpch1++;
tmpch2++;
}
if( *tmpch1 > *tmpch2 )
{
cmpresult = 1;
}
else if(*tmpch1 < *tmpch2)
{
cmpresult = -1;
}
return cmpresult;
}
char* String::strinsert(size_t n, char** dstr, const char *sstr)
{
size_t len1 = strlen(*dstr);
size_t len2 = strlen(sstr);
size_t len3 = len1+len2;
if(len2>0)
{
if(n<0) n=0;
if(n>len1) n=len1;
char* tmptr = new char[len3+1];
memcpy(tmptr, *dstr, n); //拷贝前n个字符串
memcpy(tmptr+n, sstr, len2); //插入sstr
memcpy(tmptr+n+len2, *dstr+n,len1-n+1); //拷贝后n+1个字符串
delete[] *dstr;
*dstr = tmptr;
}
return *dstr;
}
//----------------------------
//经典的字符串模式匹配KMP算法!
//----------------------------
size_t String::Find(const String& s, size_t n)
{
if((m_iLength-n)<s.m_iLength || n>m_iLength) return NOPOS; //没必要进行匹配
int *Fary = new int[s.m_iLength]; //失效匹配数组
fail(Fary, s.cstr); //初始化失效匹配数组
size_t posT = n; //目标串长索引
size_t posP = 0; //匹配串长索引
while( posT < m_iLength && posP < s.m_iLength)
{
while(cstr[posT++] == s.cstr[posP++]);
//注意最后一次比较 posP越界
if((posP-1) == s.m_iLength) //查到匹配串
{
break;
//退出while( posT < m_iLength && posP < s.m_iLength)
}
else
{
//未匹配成功,重新设定POS,并在匹配
posT += Fary[posP] + 1;
posP = Fary[posP] + 1;
}
}
delete[] Fary; //删除失效匹配数组
if( posP < s.m_iLength)
{
//没有查找到匹配项目
return NOPOS;
}
else
{
return posT - s.m_iLength;
}
}
//-------------------------------------------
//用于失效匹配数组的初始化
//-------------------------------------------
void String::fail(int *fail, const char* ch)
{
int len = strlen(ch);
fail[0] = -1; //首匹配字符
for(int i=1; i<len; i++)
{
fail[i] = -1;
// 循环计算fail[i] ,注意,i在while循环内会增加
while(ch[i] == ch[fail[i-1]+1])
{
fail[i] = fail[i-1]+1;
i++;
}
if(ch[i] == ch[fail[i-1]]) //不可以丢失这里的比较
{
fail[i] = 0;
}
else
{
fail[i] = -1;
}
}
}
- 一个精简的string类
- 一个精简的string类
- 实现精简版string类
- 一个精简的计算器源码
- 一个精简的缓存器
- 打造一个精简的BaseActivity
- 自定义的精简版String类,重载了各种字符串的运算符操作
- 第八周上机实践项目4-String类的构造(减法精简了一些哦)
- 一个java开发的超精简计算器。
- 一个精简内核配置的方法
- 如何编译一个精简的Android系统
- 如何写一个精简的Makefile
- 实现自定义ViewGroup的一个精简例子
- 一个精简的linux内核分析
- 一个类似JQuery的精简版框架
- 编译一个用于 VMworkstation 的精简内核
- C语言实现一个精简的shell
- 一个不错的MYSQL数据库备份类,PHP版,一个文件,精简版
- 数据挖掘初探
- AOP, Signal/Slot, and Decoupling
- test
- offsetParent和parentElement的区别
- 酷站欣赏
- 一个精简的string类
- 这样软件开发人才级别的划分你同意吗
- 备份虚拟主机数据的办法
- dsoframer扩展发布,免费使用(不是试用)欢迎大家下载
- 成龙《宝贝计划》精彩场景小结
- XHTML+CSS=网站重构
- array_insert.c
- 粗茶淡饭幸福长
- 一些肤浅的东西