1. class string
  2. {
  3. public:
  4. typedef size_t size_type;
  5. typedef char* iterator;
  6. typedef char value_type;
  7. private:
  8. char *start, *end_of_storage, *End;
  9. std::allocator<char> data_allocator;
  10. void DeallocateAndDestory()
  11. {
  12. data_allocator.deallocate(start, end_of_storage - start);
  13. }
  14. //重新构造元素
  15. void reallocate(size_t new_size = 0)
  16. {
  17. size_t old_size = size();
  18. if (new_size == 0)
  19. new_size = size() ? 2 * size() : 1;
  20. char* new_start = data_allocator.allocate(new_size);
  21. std::copy(start, start + size(), new_start);
  22. DeallocateAndDestory();
  23. start = new_start;
  24. End = new_start + old_size;
  25. end_of_storage = new_start + new_size;
  26. }
  27. //移动构造元素
  28. /*void reallocate()
  29. {
  30. int old_size = size();
  31. int new_size = size() ? 2 * size() : 1;
  32. char* new_start = data_allocator.allocate(new_size);
  33. char* pos = new_start;
  34. char* old_pos = start;
  35. for (int i = 0; i < old_size; i++)
  36. data_allocator.construct(pos++, std::move(*old_pos)), old_pos++;
  37. data_allocator.deallocate(start, old_size);
  38. start = new_start;
  39. End = new_start + old_size;
  40. end_of_storage = new_start + new_size;
  41. }*/
  42. public:
  43. //debug
  44. void print()
  45. {
  46. for (auto it = start; it != End; it++)
  47. std::cout << *it;
  48. std::cout << std::endl;
  49. }
  50. //Construct
  51. string()
  52. {
  53. start = end_of_storage = End = nullptr;
  54. }
  55. string(const string& rhs)
  56. {
  57. start = end_of_storage = End = nullptr;
  58. append(rhs);
  59. }
  60. string(string&& rhs)noexcept :start(rhs.start), end_of_storage(rhs.end_of_storage), End(rhs.End)
  61. {
  62. rhs.start = rhs.end_of_storage = rhs.End = nullptr;
  63. }
  64. string(const char* s)
  65. {
  66. if (s == nullptr)
  67. string();
  68. else
  69. {
  70. int cnt = 0;
  71. for (; s[cnt] != '\0'; cnt++) {}
  72. start = data_allocator.allocate(cnt);
  73. std::uninitialized_copy_n(s, cnt, start);
  74. end_of_storage = End = start + cnt;
  75. }
  76. }
  77. string(size_type n, char c)
  78. {
  79. start = data_allocator.allocate(n);
  80. std::uninitialized_fill_n(start, n, c);
  81. end_of_storage = End = start + n;
  82. }
  83. string(const char* s, size_t n)
  84. {
  85. start = data_allocator.allocate(n);
  86. std::uninitialized_copy_n(s, n, start);
  87. End = end_of_storage = start + n;
  88. }
  89. ~string()
  90. {
  91. DeallocateAndDestory();
  92. }
  93. //Iterator
  94. const iterator begin() const
  95. {
  96. return start;
  97. }
  98. const iterator end() const
  99. {
  100. return End;
  101. }
  102. iterator begin()
  103. {
  104. return start;
  105. }
  106. iterator end()
  107. {
  108. return End;
  109. }
  110. //Capacity
  111. void clear()
  112. {
  113. DeallocateAndDestory();
  114. End = start = end_of_storage = nullptr;
  115. }
  116. bool empty()const
  117. {
  118. return (start == End);
  119. }
  120. const size_type size() const
  121. {
  122. return End - start;
  123. }
  124. const size_type length() const
  125. {
  126. return size();
  127. }
  128. const size_type capacity() const
  129. {
  130. return end_of_storage - start;
  131. }
  132. void resize(size_type n)
  133. {
  134. resize(n, value_type());
  135. }
  136. void resize(size_type n, const value_type &val)
  137. {
  138. if (n <= size())
  139. {
  140. End = start + n;
  141. }
  142. else
  143. {
  144. append(string(n - size(), val));
  145. }
  146. }
  147. void reserve(size_type res_arg = 0)
  148. {
  149. if (res_arg + size() < capacity()) return;
  150. reallocate(res_arg + size());
  151. }
  152. //Modifiers
  153. value_type& operator[](size_type index)
  154. {
  155. if (index < 0 || index >= size())
  156. {
  157. std::cerr << "index out of range!" << std::endl;
  158. std::exit(1);
  159. }
  160. else
  161. {
  162. return *(start + index);
  163. }
  164. }
  165. value_type& front()
  166. {
  167. return *start;
  168. }
  169. value_type& back()
  170. {
  171. auto tmp = end();
  172. return *(--tmp);
  173. }
  174. void push_back(const value_type& val)
  175. {
  176. if (size() == capacity())
  177. reallocate();
  178. *End = val;
  179. End++;
  180. }
  181. void pop_back()
  182. {
  183. if (empty())
  184. {
  185. std::cerr << "Error : pop_back() on empty String!" << std::endl;
  186. exit(1);
  187. }
  188. End--;
  189. }
  190. void swap(string& rhs)
  191. {
  192. std::swap(start, rhs.start);
  193. std::swap(end_of_storage, rhs.end_of_storage);
  194. std::swap(End, rhs.End);
  195. }
  196. void append(const string& rhs)
  197. {
  198. if (rhs.empty()) return;
  199. if (capacity()<size() + rhs.size()) reallocate(size() + rhs.size());
  200. std::copy(rhs.start, rhs.end_of_storage, End);
  201. End += rhs.size();
  202. }
  203. void append(const char* s)
  204. {
  205. if (s == nullptr) return;
  206. size_t cnt = 0;
  207. for (; s[cnt] != '\0'; cnt++) {}
  208. if (capacity() < size() + cnt) reallocate(size() + cnt);
  209. std::uninitialized_copy_n(s, cnt, End);
  210. End += cnt;
  211. }
  212. void append(const char* s, size_t l, size_t r)
  213. {
  214. if (r <= l ) return;
  215. if (s == nullptr) return;
  216. if (capacity()<size() + r - l - 1) reallocate(size() + r - l);
  217. std::uninitialized_copy_n(s + l, r - l, End);
  218. End += r - l;
  219. }
  220. string& operator+=(const char c)
  221. {
  222. (*this).push_back(c);
  223. return *this;
  224. }
  225. string& operator+=(const string& rhs)
  226. {
  227. (*this).append(rhs);
  228. return *this;
  229. }
  230. string operator+(const string& rhs)
  231. {
  232. string tmp(*this);
  233. return tmp += rhs;
  234. }
  235. string& operator=(const string& str)
  236. {
  237. return assign(str);
  238. }
  239. string& operator=(const char* s)
  240. {
  241. return assign(string(s));
  242. }
  243. string& operator=(char c)
  244. {
  245. return assign(string((size_type)1, c));
  246. }
  247. string& assign(const string& str)
  248. {
  249. clear();
  250. append(str);
  251. return (*this);
  252. }
  253. string& assign(const char* s)
  254. {
  255. clear();
  256. if (s == nullptr) return *this;
  257. size_t cnt = 0;
  258. while (s[cnt] != '\0') cnt++;
  259. start = data_allocator.allocate(cnt);
  260. End = std::uninitialized_copy_n(s, cnt, start);
  261. end_of_storage += cnt;
  262. }
  263. string& assign(size_type n, char c)
  264. {
  265. clear();
  266. if (n == 0) return *this;
  267. start = data_allocator.allocate(n);
  268. End = end_of_storage = std::uninitialized_fill_n(start, n, c);
  269. }
  270. string& insert(size_type pos, const string& rhs)
  271. {
  272. pos = std::min(size(), pos);
  273. size_type new_size = size() + rhs.size();
  274. iterator new_start = data_allocator.allocate(new_size);
  275. std::copy(start, start + pos, new_start);
  276. std::copy(rhs.start, rhs.End, new_start + pos);
  277. std::copy(start + pos, End, new_start + pos + rhs.size());
  278. start = new_start;
  279. end_of_storage = End = new_size + new_start;
  280. return *this;
  281. }
  282. string& insert(size_type pos, const char* s, size_type n)
  283. {
  284. return insert(pos, string(s, n));
  285. }
  286. string& insert(size_type pos, const char* s)
  287. {
  288. return insert(pos, string(s));
  289. }
  290. iterator insert(iterator pos, const value_type& val)
  291. {
  292. size_type index = pos - start;
  293. if (size() == capacity())
  294. reallocate();
  295. pos = start + index;
  296. if (pos > end()) pos = end();
  297. std::copy(pos, End, pos + 1);
  298. (*pos) = val;
  299. End++;
  300. return pos;
  301. }
  302. string& insert(size_type pos, size_type num, const value_type& val)
  303. {
  304. return insert(pos, string(num, val));
  305. }
  306. string& insert(iterator pos, size_type num, const value_type& val)
  307. {
  308. return insert(pos - start, string(num, val));
  309. }
  310. string& erase(size_type pos, size_type n)
  311. {
  312. std::copy(pos + n + start, End, start + pos);
  313. End = End - n;
  314. return *this;
  315. }
  316. iterator erase(iterator pos)
  317. {
  318. std::copy(pos + 1, End, pos);
  319. End--;
  320. return pos;
  321. }
  322. iterator erase(iterator first, iterator last)
  323. {
  324. std::copy(last, End, first);
  325. End = End - (last - first);
  326. return first;
  327. }
  328. string& replace(size_t pos, size_t n, const string& str)
  329. {
  330. erase(pos, n);
  331. insert(pos, str);
  332. return *this;
  333. }
  334. string& replace(iterator i1, iterator i2, const string& str)
  335. {
  336. insert(erase(i1, i2) - start, str);
  337. return *this;
  338. }
  339. const char* c_str() const
  340. {
  341. if (empty()) return "";
  342. char* ret = new char[End - start + 1];
  343. std::uninitialized_copy(start, End, ret);
  344. ret[End - start] = '\0';
  345. return ret;
  346. }
  347. bool operator == (const string& rhs)
  348. {
  349. if (size() != rhs.size())
  350. return false;
  351. else
  352. {
  353. for (auto i = start, j = rhs.start; i != End; i++, j++)
  354. {
  355. if ((*i) != (*j))
  356. return false;
  357. }
  358. return true;
  359. }
  360. }
  361. bool operator == (const string& rhs) const
  362. {
  363. if (size() != rhs.size())
  364. return false;
  365. else
  366. {
  367. for (auto i = start, j = rhs.start; i != End; i++, j++)
  368. {
  369. if ((*i) != (*j))
  370. return false;
  371. }
  372. return true;
  373. }
  374. }
  375. int compare(const string& rhs)
  376. {
  377. iterator i = start, j = rhs.start;
  378. while (i != End && j != rhs.End)
  379. {
  380. if ((*i) > (*j))
  381. return 1;
  382. else if ((*i) < (*j))
  383. return -1;
  384. else
  385. i++, j++;
  386. }
  387. if (i == End&&j == rhs.End)
  388. return 0;
  389. else if (i == End)
  390. return -1;
  391. else
  392. return 1;
  393. }
  394. size_type copy(char* s, size_type n, size_type pos = 0) const
  395. {
  396. if (pos + n >= size())
  397. {
  398. std::cerr << "out of range" << std::endl;
  399. std::exit(1);
  400. }
  401. std::uninitialized_copy_n(start + pos, n, s);
  402. return n;
  403. }
  404. size_t find(const string& str, size_t pos = 0) const
  405. {
  406. if (size() - pos < str.size())
  407. return (size_type)(-1);
  408. for (auto it = start + pos; it != End; it++)
  409. {
  410. auto i = it, j = str.start;
  411. while (j<str.End && *i == *j)
  412. i++, j++;
  413. if (j == str.End)
  414. return it - start;
  415. }
  416. return (size_type)(-1);
  417. }
  418. size_t find(const char* s, size_t pos, size_t n) const
  419. {
  420. return find(string(s, n), pos);
  421. }
  422. size_t find(const char* s, size_t pos = 0) const
  423. {
  424. return find(string(s), pos);
  425. }
  426. size_t find(char c, size_t pos = 0) const
  427. {
  428. if (empty())
  429. return size_type(-1);
  430. else
  431. {
  432. for (auto it = start; it != End; it++)
  433. if (*it == c)
  434. return it - start;
  435. return size_type(-1);
  436. }
  437. }
  438. string substr(size_t pos = 0, size_t n = 0)
  439. {
  440. return string(start + pos, n);
  441. }
  442. size_t rfind(string& rhs, size_t pos = 0)
  443. {
  444. if (pos == 0) pos = size();
  445. for (auto it = std::min(start + pos, End - 1); it != start - 1; it--)
  446. {
  447. size_t i;
  448. for (i = 0; i < rhs.size();)
  449. if (rhs[i] == *(it + i))
  450. i++;
  451. else
  452. break;
  453. if (i == rhs.size())
  454. return it - start;
  455. }
  456. return size_t(-1);
  457. }
  458. size_t rfind(const char& c, size_t pos = 0)
  459. {
  460. if (pos == 0) pos = size();
  461. for (auto it = std::min(End - 1, start + pos); it != start; it--)
  462. {
  463. if (*it == c)
  464. return it - start;
  465. }
  466. return size_t(-1);
  467. }
  468. size_t rfind(const char* str)
  469. {
  470. return rfind(string(str));
  471. }
  472. size_t find_first_of(const string& rhs, size_t pos = 0)
  473. {
  474. for (auto it = start + pos; it != End; it++)
  475. {
  476. auto i = rhs.start;
  477. while (i != rhs.End)
  478. {
  479. if (*i == *it)
  480. break;
  481. i++;
  482. }
  483. if (i != rhs.End)
  484. return it - start;
  485. }
  486. return (size_t)-1;
  487. }
  488. size_t find_first_of(const char& c, size_t pos = 0)
  489. {
  490. for (auto it = start + pos; it != End; it++)
  491. {
  492. if (*it == c)
  493. return it - start;
  494. }
  495. return (size_t)-1;
  496. }
  497. size_t find_last_of(const char &c, size_t pos = 0)
  498. {
  499. if (pos == 0) pos = size();
  500. for (auto it = pos + start; it != start - 1; it--)
  501. if (*it == c)
  502. return it - start;
  503. return (size_t)-1;
  504. }
  505. size_t find_last_of(const char* str, size_t pos, size_t len)
  506. {
  507. size_t l = 0;
  508. for (size_t i = 0; str[i] != '\0'; i++)
  509. l++;
  510. for (auto it = start + pos; it != start + pos - len; it--)
  511. {
  512. size_t i;
  513. for (i = 0; str[i] != '\0'; i++)
  514. if (str[i] == *it)
  515. break;
  516. if (str[i] != '\0') return it - start;
  517. }
  518. return size_t(-1);
  519. }
  520. size_t find_last_of(const string& rhs, size_t pos)
  521. {
  522. for (auto it = start + pos; it != start - 1; it--)
  523. {
  524. size_t i = 0;
  525. while (rhs.start + i != rhs.End)
  526. if (*it == *(start + i))
  527. break;
  528. else
  529. i++;
  530. if (rhs.size() != i) return it - start;
  531. }
  532. return size_t(-1);
  533. }
  534. size_t find_first_not_of(const string& rhs)
  535. {
  536. for (auto it = start; it != End; it++)
  537. {
  538. size_t i = 0;
  539. while (i < rhs.size())
  540. if (*(rhs.start + i) == *it)
  541. break;
  542. else
  543. i++;
  544. if (i == rhs.size()) return it - start;
  545. }
  546. return size_t(-1);
  547. }
  548. size_t find_last_not_of(const string& rhs, size_t pos)
  549. {
  550. for (auto it = start + pos; it != start - 1; it--)
  551. {
  552. size_t i = 0;
  553. while (i < rhs.size())
  554. if (*(rhs.start + i) == *it)
  555. break;
  556. else
  557. i++;
  558. if (i == rhs.size()) return it - start;
  559. }
  560. return size_t(-1);
  561. }
  562. bool operator!=(const string& rhs)
  563. {
  564. return !(*this == rhs);
  565. }
  566. bool operator>(const string& rhs)
  567. {
  568. return compare(rhs) > 0;
  569. }
  570. bool operator>=(const string& rhs)
  571. {
  572. return compare(rhs) >= 0;
  573. }
  574. bool operator<(const string& rhs)
  575. {
  576. return compare(rhs) < 0;
  577. }
  578. bool operator<=(const string& rhs)
  579. {
  580. return compare(rhs) <= 0;
  581. }
  582. };
  583. std::ostream& operator<<(std::ostream& os, const ministl::string& rhs)
  584. {
  585. os << rhs.c_str();
  586. return os;
  587. }
  588. size_t hash_value(const string& val)
  589. {
  590. const size_t _FNV_offset_basis = 2166136261U;
  591. const size_t _FNV_prime = 16777619U;
  592. size_t ans = _FNV_offset_basis;
  593. for (auto it = val.begin(); it != val.end(); it++)
  594. {
  595. ans ^= *it;
  596. ans *= _FNV_prime;
  597. }
  598. return ans;
  599. }
  600. }

从零开始写STL-string类型的更多相关文章

  1. 从零开始写STL - 智能指针

    从零开始写STL - 智能指针 智能指针的分类及其特点: scoped_ptr:初始化获得资源控制权,在作用域结束释放资源 shared_ptr: 引用计数来控制共享资源,最后一个资源的引用被释放的时 ...

  2. 从零开始写STL—栈和队列

    从零开始写STL-栈和队列 适配器模式 意图:将一个类的接口转换成客户希望的另外一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 主要解决:主要解决在软件系统中,常常要将 ...

  3. 从零开始写STL—容器—vector

    从0开始写STL-容器-vector vector又称为动态数组,那么动态体现在哪里?vector和一般的数组又有什么区别?vector中各个函数的实现原理是怎样的,我们怎样使用会更高效? 以上内容我 ...

  4. [STL]string类型的getline函数

    3.cin.getline() 实际是cin.getline(接收字符串到m,接收个数n,结束字符).接收一个字符串,可以接收空格等,最后一个字符为‘\0’.结束符可以通过设置第三个参数自己设置,默认 ...

  5. 从零开始写STL—模板元编程之any

    any class any; (since C++17) The class any describes a type-safe container for single values of any ...

  6. 从零开始写STL—functional

    function C++11 将任意类型的可调用(Callable)对象与函数调用的特征封装到一起. 这里的类是对函数策略的封装,将函数的性质抽象成组件,便于和algorithm库配合使用 基本运算符 ...

  7. 从零开始写STL—哈希表

    static const int _stl_num_primes = 28; template<typename T, typename Hash = xhash<T>> cl ...

  8. 从零开始写STL—模板元编程之tuple

    tuple Class template std::tuple is a fixed-size collection of heterogeneous values. It is a generali ...

  9. 从零开始写STL—set/map

    这一部分只要把搜索树中暴露的接口封装一下,做一些改动. set源码剖析 template<typename T> class set { public: typedef T key_typ ...

  10. switch case :在JDK 7中,又加入了对String类型的支持,从此不用再写If-Else来判断字符串了

    switch的case语句可以处理int,short,byte,char类型的值, 因为short,byte,char都会转换成int进行处理,这一点也可以从生成的字节码看出. char a = 'e ...

随机推荐

  1. ASP.NET MVC IIS7 403.14-Forbidden

    问题描述 IIS 7上发布ASP.NET MVC程序报错:403.14-Forbidden Web 服务器被配置为不列出此目录的内容 折腾了半天,提示里面的解决方法是: 如果不希望启用目录浏览,请确保 ...

  2. Java Script 学习笔记(一)

    示例如下: JavaScript-警告(alert 消息对话框) 我们在访问网站的时候,有时会突然弹出一个小窗口,上面写着一段提示信息文字.如果你不点击“确定”,就不能对网页做任何操作,这个小窗口就是 ...

  3. Java 利用FTP上传,下载文件,遍历文件目录

    Java实现FTP上传下载文件的工具包有很多,这里我采用Java自带的API,实现FTP上传下载文件.另外JDK1.7以前的版本与其之后版本的API有了较大的改变了. 例如: JDK1.7之前 JDK ...

  4. File.Exists 文件不存在 Or FileNotFoundException

    标题警告,本文仅限走投无路,最终可能的一个问题导致. 最开始出现在找不到文件,测试发现: 看起来毫无毛病 而后各种测试: 注意看,第一行跟第三行一模一样 发现[@"‪‪‪]这两个字符有毒,如 ...

  5. [python3]PyCharm编辑器

    简介 Python有丰富的开发工具,本教程不一一进行介绍,只推荐大家使用PyCharm,因为python开发者都在用它,但缺点就是消耗电脑资源,如果你电脑配置低,就会比较卡 下载 下载地址: http ...

  6. 基于jmeter和shell的接口性能自动化

    基于jmeter和shell的接口性能自动化 1. 总体需求 由于性能测试中涉及的查询接口多,版本迭代频繁,版本更新后自动跑一轮查询业务的性能,可以及时发现一些开发修复bug触发的非预期的bug,利用 ...

  7. edquota - 编辑用户配额

    SYNOPSIS(总览) edquota [ -p proto-username ] [ -u | -g ] username... edquota [ -u | -g ] -t DESCRIPTIO ...

  8. 浅谈p值(p-value是什么)

    当我们说到p-value时,我们在说什么? “这个变量的p-value小于0.05,所以这个变量很重要” ........ 你真的知道自己在说什么么???这个p-value到底是个什么鬼?为什么小于0 ...

  9. iview 的 Carousel 走马灯 焦点图 不能用 建议换/vue-awesome-swiper

    https://www.npmjs.com/package/vue-awesome-swiper

  10. js数字转金额,ajax调用接口,后台返回html(完整页面),打开新窗口并写入html

    一.转换成金额形式 function toMoney(num){ if(num){ if(isNaN(num)) { alert("金额中含有不能识别的字符"); return; ...