思考:
replace图解:
程序完善:
DTString.h:
1 #ifndef DTSTRING_H 2 #define DTSTRING_H 3 4 #include "Object.h" 5 6 namespace DTLib 7 { 8 9 class String : Object 10 { 11 protected: 12 char* m_str; 13 int m_length; 14 15 void init(const char* s); 16 bool equal(const char* l, const char* r, int len) const; 17 18 static int* make_pmt(const char* p); 19 static int kmp(const char* s, const char* p); 20 21 public: 22 String(); 23 String(char c); 24 String(const char* s); 25 String(const String& s); 26 27 int length() const; 28 const char* str() const; 29 30 bool startWith(const char* s) const; 31 bool startWith(const String& s) const; 32 bool endOf(const char* s) const; 33 bool endOf(const String& s) const; 34 35 String& insert(int i, const char* s); 36 String& insert(int i, const String& s); 37 38 String& trim(); 39 40 int indexOf(const char* s) const; 41 int indexOf(const String& s) const; 42 43 String& remove(int i, int len); //删除指定下标,指定长度的子串 44 String& remove(const char* s); 45 String& remove(const String& s); 46 47 String& replace(const char* t, const char* s); 48 String& replace(const String& t, const char* s); 49 String& replace(const char* t, const String& s); 50 String& replace(const String& t, const String& s); 51 52 String sub(int i, int len) const; 53 54 char& operator [] (int i); 55 char operator [] (int i) const; 56 57 bool operator == (const String& s) const; 58 bool operator == (const char* s) const; 59 60 bool operator != (const String& s) const; 61 bool operator != (const char* s) const; 62 63 bool operator > (const String& s) const; 64 bool operator > (const char* s) const; 65 66 bool operator < (const String& s) const; 67 bool operator < (const char* s) const; 68 69 bool operator >= (const String& s) const; 70 bool operator >= (const char* s) const; 71 72 bool operator <= (const String& s) const; 73 bool operator <= (const char* s) const; 74 75 String operator + (const String& s) const; 76 String operator + (const char* s) const; 77 String& operator += (const String& s); 78 String& operator += (const char* s); 79 80 String operator - (const char* s) const; 81 String operator - (const String& s) const; 82 String& operator -= (const char* s); 83 String& operator -= (const String& s); 84 85 String& operator = (const String& s); 86 String& operator = (const char* s); 87 String& operator = (char c); 88 89 ~String(); 90 }; 91 92 } 93 94 95 #endif // DTSTRING_H
DTString.cpp:
1 #include <cstring> 2 #include <cstdlib> 3 #include "DTString.h" 4 #include "Exception.h" 5 6 using namespace std; 7 8 namespace DTLib 9 { 10 11 int* String::make_pmt(const char* p) // O(m) 12 { 13 int len = strlen(p); 14 15 int* ret = static_cast<int*>(malloc(sizeof(int) * len)); 16 17 if( ret != NULL ) 18 { 19 int ll = 0; 20 21 ret[0] = 0; // 第0个元素(长度为1的字符串)的ll值为0 22 23 for(int i = 1; i < len; i++) 24 { 25 //不成功的情况 26 while( (ll > 0) && (p[ll] != p[i]) ) 27 { 28 ll = ret[ll]; 29 } 30 31 // 假设最理想的情况成立 32 //在前一个ll值的基础行进行扩展,只需比对最后扩展的字符是否相等 33 //相等的话ll值加1,并写入到部分匹配表 34 if( p[ll] == p[i] ) 35 { 36 ll++; 37 } 38 39 ret[i] = ll; // 将ll值写入匹配表 40 41 } 42 } 43 44 return ret; 45 } 46 47 int String::kmp(const char* s, const char* p) //O(m) + O(n) = O(m + n) 48 { 49 int ret = -1; 50 51 int sl = strlen(s); 52 int pl = strlen(p); //子串 53 54 int* pmt = make_pmt(p); //O(m) 55 56 if( (pmt != NULL) && (0 < pl) && (pl <= sl)) 57 { 58 for( int i = 0,j = 0; i < sl; i++ ) 59 { 60 while( (j > 0) && (s[i] != p[j]) ) // j小于等于0时要退出 61 { 62 j = pmt[j]; 63 } 64 65 if( s[i] == p[j] ) 66 { 67 j++; 68 } 69 70 if( j == pl ) // j的值如果最后就是子串的长度,意味着查找到了 71 { 72 ret = i + 1 - pl; // 匹配成功时i的值停在最后一个匹配的字符上 73 break; 74 } 75 } 76 } 77 78 free(pmt); 79 80 return ret; 81 } 82 83 void String::init(const char* s) 84 { 85 m_str = strdup(s); 86 87 if( m_str ) 88 { 89 m_length = strlen(m_str); 90 } 91 else 92 { 93 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create string object ..."); 94 } 95 } 96 97 bool String::equal(const char* l, const char* r, int len) const 98 { 99 bool ret = true; 100 101 for(int i = 0; i < len && ret; i++) 102 { 103 ret = ret && (l[i] == r[i]); 104 } 105 106 return ret; 107 } 108 109 String::String() 110 { 111 init(""); 112 } 113 114 String::String(const char* s) 115 { 116 init(s ? s : ""); //空指针就转换成空字符串 117 } 118 119 String::String(const String& s) 120 { 121 init(s.m_str); 122 } 123 124 String::String(char c) 125 { 126 char s[] = {c, ' '}; 127 128 init(s); 129 } 130 131 int String::length() const 132 { 133 return m_length; 134 } 135 136 const char* String::str() const 137 { 138 return m_str; 139 } 140 141 bool String::startWith(const char* s) const 142 { 143 bool ret = ( s != NULL ); 144 145 if( ret ) 146 { 147 int len = strlen(s); 148 149 ret = (len < m_length) && equal(m_str, s, len); 150 151 } 152 153 return ret; 154 } 155 156 bool String::startWith(const String& s) const 157 { 158 return startWith(s.m_str); 159 } 160 161 bool String::endOf(const char* s) const 162 { 163 bool ret = ( s != NULL ); 164 165 if( ret ) 166 { 167 int len = strlen(s); 168 169 char* str = m_str + (m_length - len); 170 171 ret = (len < m_length) && equal(str, s, len); 172 173 } 174 175 return ret; 176 } 177 178 bool String::endOf(const String& s) const 179 { 180 return endOf(s.m_str); 181 } 182 183 String& String::insert(int i, const char* s) 184 { 185 if( (0 <= i) && (i <= m_length) ) 186 { 187 if( ( s != NULL) && ( s[0] != ' ' ) ) 188 { 189 int len = strlen(s); 190 char* str = reinterpret_cast<char*>(malloc(m_length + len + 1)); 191 192 if( str != NULL ) 193 { 194 strncpy(str, m_str, i); 195 strncpy(str + i, s, len); 196 strncpy(str + i + len, m_str + i, m_length - i); 197 198 str[m_length + len] = ' '; 199 200 free(m_str); 201 202 m_str = str; 203 m_length = m_length + len; 204 } 205 else 206 { 207 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create str object..."); 208 } 209 } 210 } 211 else 212 { 213 THROW_EXCEPTION(IndexOutOfBoundsException, "parameter i is invalid..."); 214 } 215 216 return *this; 217 } 218 219 String& String::insert(int i, const String& s) 220 { 221 return insert(i, s.m_str); 222 } 223 224 String& String::trim() 225 { 226 int b = 0; 227 int e = m_length - 1; 228 229 while( m_str[b] == ' ')b++; 230 while( m_str[e] == ' ')e--; 231 232 if( b == 0 ) 233 { 234 m_str[e + 1] = ' '; 235 236 m_length = e + 1; 237 } 238 else 239 { 240 for(int i = 0,j = b; j <= e; i++, j++) 241 { 242 m_str[i] = m_str[j]; 243 } 244 245 m_str[e - b + 1] = ' '; 246 m_length = e - b + 1; 247 } 248 249 return *this; 250 } 251 252 int String::indexOf(const char* s) const 253 { 254 return kmp(m_str, s ? s : ""); 255 } 256 257 int String::indexOf(const String& s) const 258 { 259 return kmp(m_str, s.m_str); 260 } 261 262 String& String::remove(int i, int len) 263 { 264 if( (0 <= i) && (i < m_length) ) 265 { 266 int n = i; 267 int m = i + len; 268 269 while( (n < m) && (m < m_length) ) 270 { 271 m_str[n++] = m_str[m++]; 272 } 273 274 m_str[n] = ' '; 275 m_length = n; 276 } 277 278 return *this; 279 } 280 281 String& String::remove(const char* s) 282 { 283 return remove(indexOf(s), s ? strlen(s) : 0); 284 } 285 286 String& String::remove(const String& s) 287 { 288 return remove(indexOf(s), s.length()); 289 } 290 291 String& String::replace(const char* t, const char* s) 292 { 293 int index = indexOf(t); 294 295 if( index >= 0 ) 296 { 297 remove(t); 298 insert(index, s); 299 } 300 301 return *this; 302 } 303 304 String& String::replace(const String& t, const char* s) 305 { 306 return replace(t.m_str, s); 307 } 308 309 String& String::replace(const char* t, const String& s) 310 { 311 return replace(t, s.m_str); 312 } 313 314 String& String::replace(const String& t, const String& s) 315 { 316 return replace(t.m_str, s.m_str); 317 } 318 319 String String::sub(int i, int len) const 320 { 321 String ret; 322 323 if( (0 <= i) && (i<m_length) ) 324 { 325 if( len < 0 ) len = 0; 326 if(len + i > m_length) len = m_length - i; 327 328 char* str = reinterpret_cast<char*>(malloc(len + 1)); 329 330 strncpy(str, m_str + i, len); 331 332 str[len] = ' '; 333 334 ret = str; 335 } 336 else 337 { 338 THROW_EXCEPTION(IndexOutOfBoundsException, "parameter i is invalid..."); 339 } 340 341 return ret; 342 } 343 344 char& String::operator [] (int i) 345 { 346 if( (0 <= i) && (i < m_length) ) 347 { 348 return m_str[i]; 349 } 350 else 351 { 352 THROW_EXCEPTION(IndexOutOfBoundsException, "parameter i is invalid ..."); 353 } 354 } 355 356 char String::operator [] (int i) const 357 { 358 return (const_cast<String&>(*this))[i]; 359 } 360 361 bool String::operator == (const String& s) const 362 { 363 return ( strcmp(m_str, s.m_str) == 0 ); 364 } 365 366 bool String::operator == (const char* s) const 367 { 368 return ( strcmp(m_str, s ? s : "") == 0 ); 369 } 370 371 bool String::operator != (const String& s) const 372 { 373 return !(*this == s); 374 } 375 376 bool String::operator != (const char* s) const 377 { 378 return !(*this == s); 379 } 380 381 bool String::operator > (const String& s) const 382 { 383 return (strcmp(m_str, s.m_str) > 0); 384 } 385 386 bool String::operator > (const char* s) const 387 { 388 return (strcmp(m_str, s ? s : "") > 0); 389 } 390 391 bool String::operator < (const String& s) const 392 { 393 return (strcmp(m_str, s.m_str) < 0); 394 } 395 396 bool String::operator < (const char* s) const 397 { 398 return (strcmp(m_str, s ? s : "") < 0); 399 } 400 401 bool String::operator >= (const String& s) const 402 { 403 return (strcmp(m_str, s.m_str) >= 0); 404 } 405 406 bool String::operator >= (const char* s) const 407 { 408 return (strcmp(m_str, s ? s : "") >= 0); 409 } 410 411 bool String::operator <= (const String& s) const 412 { 413 return (strcmp(m_str, s.m_str) <= 0); 414 } 415 416 bool String::operator <= (const char* s) const 417 { 418 return (strcmp(m_str, s ? s : "") <= 0); 419 } 420 421 String String::operator + (const String& s) const 422 { 423 return (*this + s.m_str); 424 } 425 426 String String::operator + (const char* s) const 427 { 428 String ret; 429 430 int len = m_length + strlen(s ? s : ""); 431 432 char* str = reinterpret_cast<char*>(malloc(len + 1)); 433 434 if( str ) 435 { 436 strcpy(str, m_str); 437 strcat(str, s ? s : ""); 438 439 free(ret.m_str); 440 441 ret.m_str = str; 442 ret.m_length = len; 443 } 444 else 445 { 446 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create str object..."); 447 } 448 449 return ret; 450 } 451 452 String& String::operator += (const String& s) 453 { 454 return (*this = *this + s.m_str); 455 } 456 457 String& String::operator += (const char* s) 458 { 459 return (*this = *this + s); 460 } 461 462 String String::operator - (const char* s) const 463 { 464 return String(*this).remove(s); 465 } 466 467 String String::operator - (const String& s) const 468 { 469 return String(*this).remove(s); 470 } 471 472 String& String::operator -= (const char* s) 473 { 474 return remove(s); 475 } 476 477 String& String::operator -= (const String& s) 478 { 479 return remove(s); 480 } 481 482 String& String::operator = (const String& s) 483 { 484 return (*this = s.m_str); 485 } 486 487 String& String::operator = (const char* s) 488 { 489 if( m_str != s ) 490 { 491 char* str = strdup(s ? s: ""); 492 493 if( str ) 494 { 495 free(m_str); 496 497 m_str = str; 498 m_length = strlen(m_str); 499 } 500 else 501 { 502 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create str object..."); 503 } 504 } 505 506 return *this; 507 } 508 509 String& String::operator = (char c) 510 { 511 char s[] = {c, ' '}; 512 513 return (*this = s); 514 } 515 516 String::~String() 517 { 518 free(m_str); 519 } 520 521 }
小结: