1 Star 0 Fork 0

杨晨龙/DTLib

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
DTString.cpp 10.30 KB
一键复制 编辑 原始数据 按行查看 历史
杨晨龙 提交于 2022-02-06 23:18 +08:00 . Add files via upload
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
/*
* This file is part of the DTLib template project, http://www.dt4sw.com
*
* The MIT License (MIT)
*
* Copyright (c) 唐佐林 (Delphi Tang)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <cstring>
#include <cstdlib>
#include "DTString.h"
#include "Exception.h"
using namespace std;
namespace DTLib
{
int* String::make_pmt(const char* p) // O(m)
{
int len = strlen(p);
int* ret = static_cast<int*>(malloc(sizeof(int) * len));
if( ret != NULL )
{
int ll = 0;
ret[0] = 0;
for(int i=1; i<len; i++)
{
while( (ll > 0) && (p[ll] != p[i]) )
{
ll = ret[ll-1];
}
if( p[ll] == p[i] )
{
ll++;
}
ret[i] = ll;
}
}
return ret;
}
int String::kmp(const char* s, const char* p) // O(m) + O(n) ==> O(m+n)
{
int ret = -1;
int sl = strlen(s);
int pl = strlen(p);
int* pmt = make_pmt(p);
if( (pmt != NULL) && (0 < pl) && (pl <= sl) )
{
for(int i=0, j=0; i<sl; i++)
{
while( (j > 0) && (s[i] != p[j]) )
{
j = pmt[j-1];
}
if( s[i] == p[j] )
{
j++;
}
if( j == pl )
{
ret = i + 1 - pl;
break;
}
}
}
free(pmt);
return ret;
}
void String::init(const char* s)
{
m_str = strdup(s);
if( m_str )
{
m_length = strlen(m_str);
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create String object ...");
}
}
String::String()
{
init("");
}
String::String(const char* s)
{
init(s ? s : "");
}
String::String(const String& s)
{
init(s.m_str);
}
String::String(char c)
{
char s[] = {c, '\0'};
init(s);
}
int String::length() const
{
return m_length;
}
const char* String::str() const
{
return m_str;
}
bool String::equal(const char* l, const char* r, int len) const
{
bool ret = true;
for(int i=0; i<len && ret; i++)
{
ret = ret && (l[i] == r[i]);
}
return ret;
}
bool String::startWith(const char* s) const
{
bool ret = (s != NULL);
if( ret )
{
int len = strlen(s);
ret = (len < m_length) && equal(m_str, s, len);
}
return ret;
}
bool String::startWith(const String& s) const
{
return startWith(s.m_str);
}
bool String::endOf(const char* s) const
{
bool ret = (s != NULL);
if( ret )
{
int len = strlen(s);
char* str = m_str + (m_length - len);
ret = (len < m_length) && equal(str, s, len);
}
return ret;
}
bool String::endOf(const String& s) const
{
return endOf(s.m_str);
}
String& String::insert(int i, const char* s)
{
if( (0 <= i) && (i <= m_length) )
{
if( (s != NULL) && (s[0] != '\0') )
{
int len = strlen(s);
char* str = reinterpret_cast<char*>(malloc(m_length + len + 1));
if( str != NULL )
{
strncpy(str, m_str, i);
strncpy(str + i, s, len);
strncpy(str + i + len, m_str + i, m_length - i);
str[m_length + len] = '\0';
free(m_str);
m_str = str;
m_length = m_length + len;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "No memory to insert string value ...");
}
}
}
else
{
THROW_EXCEPTION(IndexOutOfBoundsException, "Parameter i is invalid ...");
}
return *this;
}
String& String::insert(int i, const String& s)
{
return insert(i, s.m_str);
}
String& String::trim()
{
int b = 0;
int e = m_length - 1;
while( m_str[b] == ' ' ) b++;
while( m_str[e] == ' ' && (e >= 0)) e--;
if( b == 0 )
{
m_str[e + 1] = '\0';
m_length = e + 1;
}
else if( b == m_length )
{
m_str[0] = '\0';
m_length = 0;
}
else
{
for(int i=0, j=b; j<=e; i++, j++)
{
m_str[i] = m_str[j];
}
m_str[e - b + 1] = '\0';
m_length = e - b + 1;
}
return *this;
}
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);
}
String& String::remove(int i, int len)
{
if( (0 <= i) && (i < m_length) )
{
int n = i;
int m = i + len;
while( (n < m) && (m < m_length) )
{
m_str[n++] = m_str[m++];
}
m_str[n] = '\0';
m_length = n;
}
return *this;
}
String& String::remove(const char* s)
{
return remove(indexOf(s), s ? strlen(s) : 0);
}
String& String::remove(const String& s)
{
return remove(indexOf(s), s.length());
}
String& String::replace(const char* t, const char* s)
{
int index = indexOf(t);
if( index >= 0 )
{
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);
}
String String::sub(int i, int len) const
{
String ret;
if( (0 <= i) && (i < m_length) )
{
if( len < 0 ) len = 0;
if( len + i > m_length ) len = m_length - i;
char* str = reinterpret_cast<char*>(malloc(len + 1));
strncpy(str, m_str + i, len);
str[len] = '\0';
ret = str;
}
else
{
THROW_EXCEPTION(IndexOutOfBoundsException, "Parameter i is invalid ...");
}
return ret;
}
char& String::operator [] (int i)
{
if( (0 <= i) && (i < m_length) )
{
return m_str[i];
}
else
{
THROW_EXCEPTION(IndexOutOfBoundsException, "Parameter i is invalid ...");
}
}
char String::operator [] (int i) const
{
return (const_cast<String&>(*this))[i];
}
bool String::operator == (const String& s) const
{
return (strcmp(m_str, s.m_str) == 0);
}
bool String::operator == (const char* s) const
{
return (strcmp(m_str, s ? s : "") == 0);
}
bool String::operator != (const String& s) const
{
return !(*this == s);
}
bool String::operator != (const char* s) const
{
return !(*this == s);
}
bool String::operator > (const String& s) const
{
return (strcmp(m_str, s.m_str) > 0);
}
bool String::operator > (const char* s) const
{
return (strcmp(m_str, s ? s : "") > 0);
}
bool String::operator < (const String& s) const
{
return (strcmp(m_str, s.m_str) < 0);
}
bool String::operator < (const char* s) const
{
return (strcmp(m_str, s ? s : "") < 0);
}
bool String::operator >= (const String& s) const
{
return (strcmp(m_str, s.m_str) >= 0);
}
bool String::operator >= (const char* s) const
{
return (strcmp(m_str, s ? s : "") >= 0);
}
bool String::operator <= (const String& s) const
{
return (strcmp(m_str, s.m_str) <= 0);
}
bool String::operator <= (const char* s) const
{
return (strcmp(m_str, s ? s : "") <= 0);
}
String String::operator + (const String& s) const
{
return (*this + s.m_str);
}
String String::operator + (const char* s) const
{
String ret;
int len = m_length + strlen(s ? s : "");
char* str = reinterpret_cast<char*>(malloc(len + 1));
if( str )
{
strcpy(str, m_str);
strcat(str, s ? s : "");
free(ret.m_str);
ret.m_str = str;
ret.m_length = len;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "No memory to add String values ...");
}
return ret;
}
String& String::operator += (const String& s)
{
return (*this = *this + s.m_str);
}
String& String::operator += (const char* s)
{
return (*this = *this + s);
}
String String::operator - (const String& s) const
{
return String(*this).remove(s);
}
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);
}
String& String::operator = (const String& s)
{
return (*this = s.m_str);
}
String& String::operator = (const char* s)
{
if( m_str != s )
{
char* str = strdup(s ? s : "");
if( str )
{
free(m_str);
m_str = str;
m_length = strlen(m_str);
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "No memory to assign new String value ...");
}
}
return *this;
}
String& String::operator = (char c)
{
char s[] = {c, '\0'};
return (*this = s);
}
String::~String()
{
free(m_str);
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/thfw/DTLib.git
git@gitee.com:thfw/DTLib.git
thfw
DTLib
DTLib
main

搜索帮助