tinystl实现(第二十步:string实现)

39 篇文章 4 订阅
28 篇文章 36 订阅

经过长时间的学习终于可以开始tinystl的仿(chao)写工作了,本文参考了这位大神的github,坦白讲我只是补充了注释,因为tinystl的代码真的非常经典而我又没什么这种大型项目的经验,所以只能这样做,不过相信能够有助于大家的学习
#强烈建议按顺序阅读本专栏
string是stl中的一个重要结构,但是也是我做的最头疼的一个部分,过程非常无为,闪光点很少,但篇幅却很长。。。建议看有趣的部分就好了
string.h

#pragma once
#ifndef _STRING_H_
#define _STRING_H_

#include "Allocator.h"
#include "ReverseIterator.h"
#include "UninitializedFunctions.h"
#include "Utility.h"

#include <cstring>
#include <type_traits>

namespace mySTL {

	//the class of string
	class string {
	public:
		typedef char			value_type;
		typedef char *			iterator;
		typedef const char *	const_iterator;
		typedef reverse_iterator_t<char*> reverse_iterator;
		typedef reverse_iterator_t<const char*> const_reverse_iterator;
		typedef char&			reference;
		typedef const char&		const_reference;
		typedef size_t			size_type;
		typedef ptrdiff_t		difference_type;
		//npos is a static member constant value with the greatest possible value for an element of type size_t.
		static const size_t npos = -1;
	private:
		char *start_;
		char *finish_;
		char *endOfStorage_;

		typedef mySTL::allocator<char> dataAllocator;
	public:
		string() :start_(0), finish_(0), endOfStorage_(0) {}
		string(const string& str);
		string(string&& str);
		string(const string& str, size_t pos, size_t len = npos);
		string(const char* s);
		string(const char* s, size_t n);
		string(size_t n, char c);
		template <class InputIterator>
		string(InputIterator first, InputIterator last);

		string& operator= (const string& str);
		string& operator= (string&& str);
		string& operator= (const char* s);
		string& operator= (char c);

		~string();

		iterator begin() { return start_; }
		const_iterator begin() const { return start_; }
		iterator end() { return finish_; }
		const_iterator end() const { return finish_; }
		reverse_iterator rbegin() { return reverse_iterator(finish_); }
		const_reverse_iterator rbegin() const { return const_reverse_iterator(finish_); }
		reverse_iterator rend() { return reverse_iterator(start_); }
		const_reverse_iterator rend() const { return const_reverse_iterator(start_); }
		const_iterator cbegin() const { return start_; }
		const_iterator cend() const { return finish_; }
		const_reverse_iterator crbegin() const { return const_reverse_iterator(finish_); }
		const_reverse_iterator crend() const { return const_reverse_iterator(start_); }
		size_t size() const { return finish_ - start_; }
		size_t length() const { return size(); }
		size_t capacity() const { return endOfStorage_ - start_; }
		void clear() {
			dataAllocator::destroy(start_, finish_);
			start_ = finish_;
		}
		bool empty() const { return begin() == end(); }
		void resize(size_t n);
		void resize(size_t n, char c);
		void reserve(size_t n = 0);
		void shrink_to_fit() {
			dataAllocator::deallocate(finish_, endOfStorage_ - finish_);
			endOfStorage_ = finish_;
		}

		char& operator[] (size_t pos) { return *(start_ + pos); }
		const char& operator[] (size_t pos) const { return *(start_ + pos); }
		char& back() { return *(finish_ - 1); }
		const char& back() const { return *(finish_ - 1); }
		char& front() { return *(start_); }
		const char& front() const { return *(start_); }

		void push_back(char c) { insert(end(), c); }
		string& insert(size_t pos, const string& str);
		string& insert(size_t pos, const string& str, size_t subpos, size_t sublen = npos);
		string& insert(size_t pos, const char* s);
		string& insert(size_t pos, const char* s, size_t n);
		string& insert(size_t pos, size_t n, char c);
		iterator insert(iterator p, size_t n, char c);
		iterator insert(iterator p, char c);
		template <class InputIterator>
		iterator insert(iterator p, InputIterator first, InputIterator last);
		string& append(const string& str);
		string& append(const string& str, size_t subpos, size_t sublen = npos);
		string& append(const char* s);
		string& append(const char* s, size_t n);
		string& append(size_t n, char c);
		template <class InputIterator>
		string& append(InputIterator first, InputIterator last);
		string& operator+= (const string& str);
		string& operator+= (const char* s);
		string& operator+= (char c);

		void pop_back() { erase(end() - 1, end()); }
		string& erase(size_t pos = 0, size_t len = npos);
		iterator erase(iterator p);
		iterator erase(iterator first, iterator last);

		string& replace(size_t pos, size_t len, const string& str);
		string& replace(iterator i1, iterator i2, const string& str);
		string& replace(size_t pos, size_t len, const string& str, size_t subpos, size_t sublen = npos);
		string& replace(size_t pos, size_t len, const char* s);
		string& replace(iterator i1, iterator i2, const char* s);
		string& replace(size_t pos, size_t len, const char* s, size_t n);
		string& replace(iterator i1, iterator i2, const char* s, size_t n);
		string& replace(size_t pos, size_t len, size_t n, char c);
		string& replace(iterator i1, iterator i2, size_t n, char c);
		template <class InputIterator>
		string& replace(iterator i1, iterator i2, InputIterator first, InputIterator last);

		void swap(string& str) {
			mySTL::swap(start_, str.start_);
			mySTL::swap(finish_, str.finish_);
			mySTL::swap(endOfStorage_, str.endOfStorage_);
		}
		size_t copy(char* s, size_t len, size_t pos = 0) const {
			auto ptr =mySTL::uninitialized_copy(begin() + pos, begin() + pos + len, s);
			return (size_t)(ptr - s);
		}

		size_t find(const string& str, size_t pos = 0) const;
		size_t find(const char* s, size_t pos = 0) const;
		size_t find(const char* s, size_t pos, size_t n) const;
		size_t find(char c, size_t pos = 0) const;
		size_t rfind(const string& str, size_t pos = npos) const;
		size_t rfind(const char* s, size_t pos = npos) const;
		size_t rfind(const char* s, size_t pos, size_t n) const;
		size_t rfind(char c, size_t pos = npos) const;
		size_t find_first_of(const string& str, size_t pos = 0) const;
		size_t find_first_of(const char* s, size_t pos = 0) const;
		size_t find_first_of(const char* s, size_t pos, size_t n) const;
		size_t find_first_of(char c, size_t pos = 0) const;
		size_t find_last_of(const string& str, size_t pos = npos) const;
		size_t find_last_of(const char* s, size_t pos = npos) const;
		size_t find_last_of(const char* s, size_t pos, size_t n) const;
		size_t find_last_of(char c, size_t pos = npos) const;
		size_t find_first_not_of(const string& str, size_t pos = 0) const;
		size_t find_first_not_of(const char* s, size_t pos = 0) const;
		size_t find_first_not_of(const char* s, size_t pos, size_t n) const;
		size_t find_first_not_of(char c, size_t pos = 0) const;
		size_t find_last_not_of(const string& str, size_t pos = npos) const;
		size_t find_last_not_of(const char* s, size_t pos = npos) const;
		size_t find_last_not_of(const char* s, size_t pos, size_t n) const;
		size_t find_last_not_of(char c, size_t pos = npos) const;

		string substr(size_t pos = 0, size_t len = npos) const {
			len = changeVarWhenEuqalNPOS(len, size(), pos);
			return string(begin() + pos, begin() + pos + len);
		}

		int compare(const string& str) const;
		int compare(size_t pos, size_t len, const string& str) const;
		int compare(size_t pos, size_t len, const string& str,
			size_t subpos, size_t sublen = npos) const;
		int compare(const char* s) const;
		int compare(size_t pos, size_t len, const char* s) const;
		int compare(size_t pos, size_t len, const char* s, size_t n) const;
	private:
		void moveData(string& str);
		//插入时空间不足的情况
		template<class InputIterator>
		iterator insert_aux_copy(iterator p, InputIterator first, InputIterator last);
		//插入时空间不足的情况
		iterator insert_aux_filln(iterator p, size_t n, value_type c);
		size_type getNewCapacity(size_type len)const;
		void allocateAndFillN(size_t n, char c);
		template<class InputIterator>
		void allocateAndCopy(InputIterator first, InputIterator last);
		void string_aux(size_t n, char c, std::true_type);
		template<class InputIterator>
		void string_aux(InputIterator first, InputIterator last, std::false_type);
		void destroyAndDeallocate();
		size_t rfind_aux(const_iterator cit, size_t pos, size_t lengthOfS, int cond)const;
		size_t find_aux(const_iterator cit, size_t pos, size_t lengthOfS, size_t cond)const;
		int compare_aux(size_t pos, size_t len, const_iterator cit, size_t subpos, size_t sublen)const;
		bool isContained(char ch, const_iterator first, const_iterator last)const;
		size_t changeVarWhenEuqalNPOS(size_t var, size_t minuend, size_t minue)const;
	public:
		friend std::ostream& operator <<(std::ostream& os, const string&str);
		friend std::istream& operator >> (std::istream& is, string& str);
		friend string operator+ (const string& lhs, const string& rhs);
		friend string operator+ (const string& lhs, const char* rhs);
		friend string operator+ (const char* lhs, const string& rhs);
		friend string operator+ (const string& lhs, char rhs);
		friend string operator+ (char lhs, const string& rhs);
		friend bool operator== (const string& lhs, const string& rhs);
		friend bool operator== (const char*   lhs, const string& rhs);
		friend bool operator== (const string& lhs, const char*   rhs);
		friend bool operator!= (const string& lhs, const string& rhs);
		friend bool operator!= (const char*   lhs, const string& rhs);
		friend bool operator!= (const string& lhs, const char*   rhs);
		friend bool operator<  (const string& lhs, const string& rhs);
		friend bool operator<  (const char*   lhs, const string& rhs);
		friend bool operator<  (const string& lhs, const char*   rhs);
		friend bool operator<= (const string& lhs, const string& rhs);
		friend bool operator<= (const char*   lhs, const string& rhs);
		friend bool operator<= (const string& lhs, const char*   rhs);
		friend bool operator>  (const string& lhs, const string& rhs);
		friend bool operator>  (const char*   lhs, const string& rhs);
		friend bool operator>  (const string& lhs, const char*   rhs);
		friend bool operator>= (const string& lhs, const string& rhs);
		friend bool operator>= (const char*   lhs, const string& rhs);
		friend bool operator>= (const string& lhs, const char*   rhs);
		friend void swap(string& x, string& y);
		friend std::istream& getline(std::istream& is, string& str, char delim);
		friend std::istream& getline(std::istream& is, string& str);
	};// end of string

	template<class InputIterator>
	string::string(InputIterator first, InputIterator last) {
		//处理指针和数字间的区别的函数
		string_aux(first, last, typename std::is_integral<InputIterator>::type());
	}
	template <class InputIterator>
	string::iterator string::insert_aux_copy(iterator p, InputIterator first, InputIterator last) {
		size_t lengthOfInsert = last - first;
		auto newCapacity = getNewCapacity(lengthOfInsert);
		iterator newStart = dataAllocator::allocate(newCapacity);
		iterator newFinish = TinySTL::uninitialized_copy(start_, p, newStart);
		newFinish = mySTL::uninitialized_copy(first, last, newFinish);
		auto res = newFinish;
		newFinish = mySTL::uninitialized_copy(p, finish_, newFinish);

		destroyAndDeallocate();
		start_ = newStart;
		finish_ = newFinish;
		endOfStorage_ = start_ + newCapacity;
		return res;
	}
	template <class InputIterator>
	string::iterator string::insert(iterator p, InputIterator first, InputIterator last) {
		auto lengthOfLeft = capacity() - size();
		size_t lengthOfInsert = distance(first, last);
		if (lengthOfInsert <= lengthOfLeft) {
			for (iterator it = finish_ - 1; it >= p; --it) {
				*(it + lengthOfInsert) = *(it);
			}
			mySTL::uninitialized_copy(first, last, p);
			finish_ += lengthOfInsert;
			return (p + lengthOfInsert);
		}
		else {
			return insert_aux_copy(p, first, last);
		}
	}
	template <class InputIterator>
	string& string::append(InputIterator first, InputIterator last) {
		insert(end(), first, last);
		return *this;
	}
	template <class InputIterator>
	//先删除后插入,好粗暴啊
	string& string::replace(iterator i1, iterator i2,
		InputIterator first, InputIterator last) {
		auto ptr = erase(i1, i2);
		insert(ptr, first, last);
		return *this;
	}
	template<class InputIterator>
	void string::allocateAndCopy(InputIterator first, InputIterator last) {
		start_ = dataAllocator::allocate(last - first);
		finish_ = mySTL::uninitialized_copy(first, last, start_);
		endOfStorage_ = finish_;
	}
	template<class InputIterator>
	void string::string_aux(InputIterator first, InputIterator last, std::false_type) {
		allocateAndCopy(first, last);
	}
}
#endif

string.cpp

#include"../String.h"
#include<iostream>
namespace mySTL {
	const size_t string::npos;

	string::string(size_t n, char c) {
		allocateAndFillN(n, c);
	}
	string::string(const char* s) {
		allocateAndCopy(s, s + strlen(s));
	}
	string::string(const char* s, size_t n) {
		allocateAndCopy(s, s + n);
	}
	string::string(const string& str) {
		allocateAndCopy(str.start_, str.finish_);
	}
	string::string(string&& str) {
		moveData(str);
	}
	string::string(const string& str, size_t pos, size_t len) {
		len = changeVarWhenEuqalNPOS(len, str.size(), pos);
		allocateAndCopy(str.start_ + pos, str.start_ + pos + len);
	}
	string::~string() {
		destroyAndDeallocate();
	}
	string& string::operator= (const string& str) {
		if (this != &str) {
			destroyAndDeallocate();
			allocateAndCopy(str.start_, str.finish_);
		}
		return *this;
	}
	string& string::operator= (string&& str) {
		if (this != &str) {
			moveData(str);
		}
		return *this;
	}
	string& string::operator= (const char* s) {
		destroyAndDeallocate();
		allocateAndCopy(s, s + strlen(s));
		return *this;
	}
	string& string::operator= (char c) {
		destroyAndDeallocate();
		allocateAndFillN(1, c);
		return *this;
	}
	void string::resize(size_t n) {
		resize(n, value_type());
	}
	void string::resize(size_t n, char c) {
		if (n < size()) {
			dataAllocator::destroy(start_ + n, finish_);
			finish_ = start_ + n;
		}
		else if (n > size() && n <= capacity()) {
			auto lengthOfInsert = n - size();
			finish_ = mySTL::uninitialized_fill_n(finish_, lengthOfInsert, c);
		}
		else if (n > capacity()) {
			auto lengthOfInsert = n - size();
			iterator newStart = dataAllocator::allocate(getNewCapacity(lengthOfInsert));
			iterator newFinish = mySTL::uninitialized_copy(begin(), end(), newStart);
			newFinish = mySTL::uninitialized_fill_n(newFinish, lengthOfInsert, c);

			destroyAndDeallocate();
			start_ = newStart;
			finish_ = newFinish;
			endOfStorage_ = start_ + n;
		}
	}
	void string::reserve(size_t n) {
		if (n <= capacity())
			return;
		iterator newStart = dataAllocator::allocate(n);
		iterator newFinish = mySTL::uninitialized_copy(begin(), end(), newStart);
		destroyAndDeallocate();
		start_ = newStart;
		finish_ = newFinish;
		endOfStorage_ = start_ + n;
	}
	string& string::insert(size_t pos, const string& str) {
		insert(start_ + pos, str.begin(), str.end());
		return *this;
	}
	//???
	string& string::insert(size_t pos, const string& str, size_t subpos, size_t sublen) {
		sublen = changeVarWhenEuqalNPOS(sublen, str.size(), subpos);
		insert(begin() + pos, str.begin() + subpos, str.begin() + subpos + sublen);
		return *this;
	}
	//对字符指针特殊处理
	string& string::insert(size_t pos, const char* s) {
		insert(begin() + pos, s, s + strlen(s));
		return *this;
	}
	string& string::insert(size_t pos, const char* s, size_t n) {
		insert(begin() + pos, s, s + n);
		return *this;
	}
	//
	string::iterator string::insert_aux_filln(iterator p, size_t n, value_type c) {
		auto newCapacity = getNewCapacity(n);
		iterator newStart = dataAllocator::allocate(newCapacity);
		iterator newFinish = mySTL::uninitialized_copy(start_, p, newStart);
		newFinish = mySTL::uninitialized_fill_n(newFinish, n, c);
		auto res = newFinish;
		newFinish = mySTL::uninitialized_copy(p, finish_, newFinish);

		destroyAndDeallocate();
		start_ = newStart;
		finish_ = newFinish;
		endOfStorage_ = start_ + newCapacity;
		return res;
	}
	//输入pos的insert
	string& string::insert(size_t pos, size_t n, char c) {
		insert(begin() + pos, n, c);
		return *this;
	}
	//
	string::iterator string::insert(iterator p, size_t n, char c) {
		auto lengthOfLeft = capacity() - size();
		if (n <= lengthOfLeft) {
			for (iterator it = finish_ - 1; it >= p; --it) {
				*(it + n) = *(it);
			}
			mySTL::uninitialized_fill_n(p, n, c);
			finish_ += n;
			return (p + n);
		}
		else {
			return insert_aux_filln(p, n, c);
		}
	}
	//
	string::iterator string::insert(iterator p, char c) {
		return insert(p, 1, c);
	}
	string& string::operator+= (const string& str) {
		insert(size(), str);
		return *this;
	}
	string& string::operator+= (const char* s) {
		insert(size(), s);
		return *this;
	}
	string& string::operator+= (char c) {
		insert(end(), c);
		return *this;
	}
	//apend调用+=
	string& string::append(const string& str) {
		(*this) += str;
		return *this;
	}
	string& string::append(const string& str, size_t subpos, size_t sublen) {
		sublen = changeVarWhenEuqalNPOS(sublen, str.size(), subpos);
		insert(size(), str, subpos, sublen);
		return *this;
	}
	string& string::append(const char* s) {
		(*this) += s;
		return *this;
	}
	string& string::append(const char* s, size_t n) {
		insert(size(), s, n);
		return *this;
	}
	string& string::append(size_t n, char c) {
		insert(end(), n, c);
		return *this;
	}
	//移走后删除
	string::iterator string::erase(iterator first, iterator last) {
		size_t lengthOfMove = finish_ - last;
		for (auto i = 0; i != lengthOfMove; ++i) {
			*(first + i) = *(last + i);
		}
		dataAllocator::destroy(first + lengthOfMove, finish_);
		finish_ = first + lengthOfMove;
		return first;

	}
	//调整范围
	string& string::erase(size_t pos, size_t len) {
		len = changeVarWhenEuqalNPOS(len, size(), pos);
		erase(begin() + pos, begin() + pos + len);
		return *this;
	}
	string::iterator string::erase(iterator p) {
		//return erase(p, end());
		//bug fix
		//2014.12.24
		return erase(p, p + 1);
	}
	//	对各种形态的调整
	string& string::replace(size_t pos, size_t len, const string& str) {
		return replace(begin() + pos, begin() + pos + len, str.begin(), str.end());
	}
	string& string::replace(iterator i1, iterator i2, const string& str) {
		return replace(i1, i2, str.begin(), str.end());
	}
	string& string::replace(size_t pos, size_t len, const string& str, size_t subpos, size_t sublen) {
		sublen = changeVarWhenEuqalNPOS(sublen, str.size(), subpos);
		return replace(begin() + pos, begin() + pos + len, str.begin() + subpos, str.begin() + subpos + sublen);
	}
	string& string::replace(size_t pos, size_t len, const char* s) {
		return replace(begin() + pos, begin() + pos + len, s, s + strlen(s));
	}
	string& string::replace(iterator i1, iterator i2, const char* s) {
		return replace(i1, i2, s, s + strlen(s));
	}
	string& string::replace(iterator i1, iterator i2, size_t n, char c) {
		auto ptr = erase(i1, i2);
		insert(ptr, n, c);
		return *this;
	}
	string& string::replace(size_t pos, size_t len, const char* s, size_t n) {
		return replace(begin() + pos, begin() + pos + len, s, s + n);
	}
	string& string::replace(iterator i1, iterator i2, const char* s, size_t n) {
		return replace(i1, i2, s, s + n);
	}
	string& string::replace(size_t pos, size_t len, size_t n, char c) {
		return replace(begin() + pos, begin() + pos + len, n, c);
	}
	//查找:居然没用kmp。。。
	size_t string::find_aux(const_iterator cit, size_t pos, size_t lengthOfS, size_t cond)const {
		size_t i, j;
		for (i = pos; i != cond; ++i) {
			for (j = 0; j != lengthOfS; ++j) {
				if (*(begin() + i + j) != cit[j])
					break;
			}
			if (j == lengthOfS)
				return i;
		}
		return npos;
	}
	//对字符指针做处理
	size_t string::find(const char* s, size_t pos, size_t n) const {
		size_t lenghtOfS = strlen(s);
		return find_aux(s, pos, n, size());
	}
	//
	size_t string::find(const string& str, size_t pos) const {
		size_t lengthOfS = str.size();
		if (size() - pos < lengthOfS)
			return npos;
		return find_aux(str.cbegin(), pos, lengthOfS, size());
	}
	size_t string::find(const char* s, size_t pos) const {
		return find(s, pos, strlen(s));
	}
	size_t string::find(char c, size_t pos) const {
		for (auto cit = cbegin() + pos; cit != cend(); ++cit) {
			if (*cit == c)
				return cit - cbegin();
		}
		return npos;
	}
	size_t string::rfind(char c, size_t pos) const {
		pos = changeVarWhenEuqalNPOS(pos, size(), 1);
		for (auto cit = cbegin() + pos; cit >= cbegin(); --cit) {
			if (*cit == c)
				return cit - cbegin();
		}
		return npos;
	}
	//反向查找
	size_t string::rfind_aux(const_iterator cit, size_t pos, size_t lengthOfS, int cond)const {
		int i, j;
		for (i = pos + lengthOfS; i >= cond; --i) {
			for (j = 0; j != lengthOfS; ++j) {
				if (*(begin() + i + j) != cit[j])
					break;
			}
			if (j == lengthOfS)
				return i;
		}
		return npos;
	}
	//
	size_t string::rfind(const string& str, size_t pos) const {
		auto lengthOfS = str.size();
		pos = changeVarWhenEuqalNPOS(pos, size(), 1);
		return rfind_aux(str.begin(), pos, lengthOfS, 0);
	}
	size_t string::rfind(const char* s, size_t pos) const {
		pos = changeVarWhenEuqalNPOS(pos, size(), 1);
		return rfind(s, pos, strlen(s));
	}
	size_t string::rfind(const char* s, size_t pos, size_t n) const {
		auto lengthOfS = strlen(s);
		return rfind_aux(s, pos, n, 0);
	}
	int string::compare(const string& str) const {
		return compare(0, size(), str, 0, str.size());
	}
	int string::compare(size_t pos, size_t len, const string& str) const {
		return compare(pos, len, str, 0, str.size());
	}
	int string::compare_aux(size_t pos, size_t len, const_iterator cit, size_t subpos, size_t sublen)const {
		size_t i, j;
		for (i = 0, j = 0; i != len && j != sublen; ++i, ++j) {
			if ((*this)[pos + i] < cit[subpos + j])
				return -1;
			else if ((*this)[pos + i] > cit[subpos + j])
				return 1;
		}
		if (i == len && j == sublen)
			return 0;
		else if (i == len)
			return -1;
		else
			return 1;
	}
	int string::compare(size_t pos, size_t len, const string& str, size_t subpos, size_t sublen) const {
		return compare_aux(pos, len, str.begin(), subpos, sublen);
	}
	int string::compare(const char* s) const {
		return compare(0, size(), s, strlen(s));
	}
	int string::compare(size_t pos, size_t len, const char* s) const {
		return compare(pos, len, s, strlen(s));
	}
	int string::compare(size_t pos, size_t len, const char* s, size_t n) const {
		return compare_aux(pos, len, s, 0, n);
	}
	size_t string::find_first_of(const string& str, size_t pos) const {
		return find_first_of(str.begin(), pos, str.size());
	}
	size_t string::find_first_of(const char* s, size_t pos) const {
		return find_first_of(s, pos, strlen(s));
	}
	size_t string::find_first_of(const char* s, size_t pos, size_t n) const {

		for (size_t i = pos; i != size(); ++i) {
			if (isContained((*this)[i], s, s + n))
				return i;
		}
		return npos;
	}
	size_t string::find_first_of(char c, size_t pos) const {
		return find(c, pos);
	}
	size_t string::find_first_not_of(const string& str, size_t pos) const {
		return find_first_not_of(str.begin(), pos, str.size());
	}
	size_t string::find_first_not_of(const char* s, size_t pos) const {
		return find_first_not_of(s, pos, strlen(s));
	}
	size_t string::find_first_not_of(const char* s, size_t pos, size_t n) const {
		for (size_t i = pos; i != size(); ++i) {
			if (!isContained((*this)[i], s, s + n))
				return i;
		}
		return npos;
	}
	size_t string::find_first_not_of(char c, size_t pos) const {
		for (size_t i = pos; i != size(); ++i) {
			if ((*this)[i] != c)
				return i;
		}
		return npos;
	}
	size_t string::find_last_of(char c, size_t pos) const {
		return rfind(c, pos);
	}
	size_t string::find_last_not_of(const string& str, size_t pos) const {
		pos = changeVarWhenEuqalNPOS(pos, size(), 1);
		return find_last_not_of(str.begin(), pos, str.size());
	}
	size_t string::find_last_not_of(const char* s, size_t pos) const {
		pos = changeVarWhenEuqalNPOS(pos, size(), 1);
		return find_last_not_of(s, pos, strlen(s));
	}
	size_t string::find_last_not_of(const char* s, size_t pos, size_t n) const {
		for (size_t i = pos; i >= 0; --i) {
			if (!isContained((*this)[i], s, s + n))
				return i;
		}
		return npos;
	}
	size_t string::find_last_not_of(char c, size_t pos) const {
		pos = changeVarWhenEuqalNPOS(pos, size(), 1);
		for (int i = pos; i >= 0; --i) {
			if ((*this)[i] != c)
				return i;
		}
		return npos;
	}
	//输入输出,基本上是本文件最有营养的部分了
	std::ostream& operator <<(std::ostream& os, const string&str) {
		for (const auto ch : str) {
			os << ch;
		}
		return os;
	}
	//
	std::istream& operator >> (std::istream& is, string& str) {
		char ch;
		string::size_type oldSize = str.size(), index = 0;
		bool hasPrevBlank = false;//一个没有用的变量
		while (is.get(ch)) {//跳过前导空白
			if (isblank(ch) || ch == '\n')
				hasPrevBlank = true;
			else
				break;
		}
		is.putback(ch);
		str.clear();
		while (is.get(ch)) {
			if (ch != EOF && !isblank(ch) && ch != '\n') {
				str.push_back(ch);//没到尾继续
			}
			else
				break;
		}
		return is;
	}
	//getline录入整行
	std::istream& getline(std::istream& is, string& str, char delim) {
		char ch;
		str.clear();
		while (is.get(ch)) {
			if (ch == delim)
				break;
			else
				str.push_back(ch);
		}
		return is;
	}
	std::istream& getline(std::istream& is, string& str) {
		return getline(is, str, '\n');
	}
	//
	string operator+ (const string& lhs, const string& rhs) {
		string res(lhs);
		return res += rhs;
	}
	string operator+ (const string& lhs, const char* rhs) {
		string res(lhs);
		return res += rhs;
	}
	string operator+ (const char* lhs, const string& rhs) {
		string res(lhs);
		return res += rhs;
	}
	string operator+ (const string& lhs, char rhs) {
		string res(lhs);
		return res += rhs;
	}
	string operator+ (char lhs, const string& rhs) {
		string res(1, lhs);
		return res += rhs;
	}
	//对char*额外处理
	bool operator== (const string& lhs, const string& rhs) {
		if (lhs.size() == rhs.size()) {
			for (auto cit1 = lhs.cbegin(), cit2 = rhs.cbegin();
				cit1 != lhs.cend() && cit2 != rhs.cend();
				++cit1, ++cit2) {
				if (*cit1 != *cit2)
					return false;
			}
			return true;
		}
		return false;
	}
	bool operator== (const char*   lhs, const string& rhs) {
		return rhs == lhs;
	}
	bool operator== (const string& lhs, const char*   rhs) {
		size_t len = strlen(rhs);
		if (lhs.size() == len) {
			const char *p = rhs;
			for (string::const_iterator cit = lhs.cbegin();
				cit != lhs.cend() && p != rhs + len;
				++cit, ++p) {
				if (*cit != *p)
					return false;
			}
			return true;
		}
		return false;
	}
	bool operator!= (const string& lhs, const string& rhs) {
		return !(lhs == rhs);
	}
	bool operator!= (const char*   lhs, const string& rhs) {
		return !(lhs == rhs);
	}
	bool operator!= (const string& lhs, const char*   rhs) {
		return !(lhs == rhs);
	}
	bool operator<  (const string& lhs, const string& rhs) {
		return !(lhs >= rhs);
	}
	bool operator<  (const char*   lhs, const string& rhs) {
		return !(lhs >= rhs);
	}
	bool operator<  (const string& lhs, const char*   rhs) {
		return !(lhs >= rhs);
	}
	namespace {
		template<class Iterator1, class Iterator2>
		bool lessEqual_aux(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
			for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
				if (*first1 < *first2)
					return true;
				else if (*first1 > *first2)
					return false;
			}
			//逐个判断再比头尾,非常漂亮
			if ((first1 == last1 && first2 == last2)// ==
				|| (first1 == last1))// <
				return true;
			else
				return false;
		}
	}
	bool operator<= (const string& lhs, const string& rhs) {
		return lessEqual_aux(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
	}
	bool operator<= (const char*   lhs, const string& rhs) {
		return lessEqual_aux(lhs, lhs + strlen(lhs), rhs.cbegin(), rhs.cend());
	}
	bool operator<= (const string& lhs, const char*   rhs) {
		return lessEqual_aux(lhs.cbegin(), lhs.cend(), rhs, rhs + strlen(rhs));
	}
	bool operator>  (const string& lhs, const string& rhs) {
		return !(lhs <= rhs);
	}
	bool operator>  (const char*   lhs, const string& rhs) {
		return !(lhs <= rhs);
	}
	bool operator>  (const string& lhs, const char*   rhs) {
		return !(lhs <= rhs);
	}
	namespace {
		template<class Iterator1, class Iterator2>
		bool greaterEqual_aux(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) {
			for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
				if (*first1 > *first2)
					return true;
				else if (*first1 < *first2)
					return false;
			}
			if ((first1 == last1 && first2 == last2)// ==
				|| (first2 == last2))// >
				return true;
			else
				return false;
		}
	}
	bool operator>= (const string& lhs, const string& rhs) {
		return greaterEqual_aux(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
	}
	bool operator>= (const char*   lhs, const string& rhs) {
		return greaterEqual_aux(lhs, lhs + strlen(lhs), rhs.cbegin(), rhs.cend());
	}
	bool operator>= (const string& lhs, const char*   rhs) {
		return greaterEqual_aux(lhs.cbegin(), lhs.cend(), rhs, rhs + strlen(rhs));
	}
	void swap(string& x, string& y) {
		x.swap(y);
	}
	//移走数据
	void string::moveData(string& str) {
		start_ = str.start_;
		finish_ = str.finish_;
		endOfStorage_ = str.endOfStorage_;
		str.start_ = str.finish_ = str.endOfStorage_ = 0;
	}
	string::size_type string::getNewCapacity(size_type len)const {
		size_type oldCapacity = endOfStorage_ - start_;
		auto res = mySTL::max(oldCapacity, len);
		//size_type newCapacity = (oldCapacity != 0 ? (oldCapacity + res) : 1);
		auto newCapacity = oldCapacity + res;
		return newCapacity;
	}
	void string::allocateAndFillN(size_t n, char c) {
		start_ = dataAllocator::allocate(n);
		finish_ = mySTL::uninitialized_fill_n(start_, n, c);
		endOfStorage_ = finish_;
	}
	void string::string_aux(size_t n, char c, std::true_type) {
		allocateAndFillN(n, c);
	}
	void string::destroyAndDeallocate() {
		dataAllocator::destroy(start_, finish_);
		dataAllocator::deallocate(start_, endOfStorage_ - start_);
	}
	bool string::isContained(char ch, const_iterator first, const_iterator last)const {
		for (auto cit = first; cit != last; ++cit) {
			if (*cit == ch)
				return true;
		}
		return false;
	}
	size_t string::changeVarWhenEuqalNPOS(size_t var, size_t minuend, size_t minue)const {
		return (var == npos ? minuend - minue : var);
	}

}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用 `std::string` 的一些成员函数实现字符串的 split 和 join 操作。 首先,实现字符串的 split 可以使用 `std::stringstream` 和 `std::getline` 来实现,示例代码如下: ```c++ #include <sstream> #include <vector> #include <string> std::vector<std::string> split(const std::string& s, char delimiter) { std::vector<std::string> tokens; std::stringstream ss(s); std::string token; while (std::getline(ss, token, delimiter)) { tokens.push_back(token); } return tokens; } ``` 上述代码中,使用 `std::stringstream` 将字符串转化为 `std::string` 流,然后使用 `std::getline` 函数根据指定的分隔符 `delimiter` 进行分割,将分割后的字符串存储到 `std::vector<std::string>` 中。 接下来,实现字符串的 join 可以使用 `std::stringstream` 和 `std::copy` 来实现,示例代码如下: ```c++ #include <sstream> #include <algorithm> #include <iterator> #include <vector> #include <string> std::string join(const std::vector<std::string>& strs, const std::string& delimiter) { std::stringstream ss; std::copy(strs.begin(), strs.end(), std::ostream_iterator<std::string>(ss, delimiter.c_str())); std::string joined_str = ss.str(); if (joined_str.size() > delimiter.size()) { joined_str.erase(joined_str.size() - delimiter.size()); } return joined_str; } ``` 上述代码中,使用 `std::stringstream` 将 `std::vector<std::string>` 中的字符串转化为 `std::string` 流,并使用 `std::copy` 函数将字符串按照指定的分隔符 `delimiter` 进行拼接,最后返回拼接后的字符串。需要注意的是,由于最后一个字符串也会跟随一个分隔符,因此需要在返回的字符串中将最后一个分隔符去掉。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值