国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C++_String增刪查改模擬實(shí)現(xiàn)

這篇具有很好參考價(jià)值的文章主要介紹了C++_String增刪查改模擬實(shí)現(xiàn)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

前言

本篇博客僅僅實(shí)現(xiàn)存儲字符的string。同時由于C++string庫設(shè)計(jì)的不合理,博主僅實(shí)現(xiàn)一些最常見的增刪查改接口!
接下來給出的接口都是基于以下框架:

namespace achieveString
{
	class string
	{

	private:
		char* _str;
		size_t _capacity;
		size_t _size;
	};
}

一、string默認(rèn)構(gòu)造、析構(gòu)函數(shù)、拷貝構(gòu)造、賦值重載

1.1 默認(rèn)構(gòu)造

博主在這僅僅提供如無參和帶參默認(rèn)構(gòu)造接口:

//無參默認(rèn)構(gòu)造
string()
	:_str(new char[1]{'\0'})
	,_capacity(0)
	,_size(0)
{ }
//帶參默認(rèn)構(gòu)造
string(const char* str = "")
	:_capacity(strlen(str))
	,_size(_capacity)
{
	_str = new char[_capacity + 1];
	strcpy(_str, str);
}

小tips:

  1. C++string標(biāo)準(zhǔn)庫中,無參構(gòu)造并不是空間為0,直接置為空指針。而是開一個字節(jié),并存放‘\0’。(C++中支持無參構(gòu)造一個對象后,直接在后面插入數(shù)據(jù),也從側(cè)面說明了這點(diǎn))
  2. 由于C++構(gòu)造函數(shù)不管寫不寫都會走初始化列表的特性,所以這里博主也走初始化列表。
  3. string中,_capacity和_size都不包含空指針,所以帶參構(gòu)造要多開一個空間,用來存儲’\0’。

1.2 析構(gòu)函數(shù)

~string()
{
	delete[] _str;
	_str = nullptr;
	_size = _capacity = 0;
}

1.3 拷貝構(gòu)造

傳統(tǒng)寫法:

string(const string& s)
{
	_str = new char[s._capacity + 1];
	strcpy(_str, s._str);
	_size = s._size;
	_capacity = s._capacity;
}

現(xiàn)代寫法:現(xiàn)代寫法的核心在于:將拷貝數(shù)據(jù)的工作交給別人來做,最后將成果交換一樣即可。

//交換
void swap(string& s)
{
	std::swap(_str, s._str);
	std::swap(_size, s._size);
	std::swap(_capacity, s._capacity);
}

//現(xiàn)代寫法
string(const string& s)
	:_str(nullptr)
	,_size(0)
	,_capacity(0)
{
	string tmp(s._str);
	swap(tmp);
}

tips:現(xiàn)代寫法中,拷貝構(gòu)造是數(shù)據(jù)需初始化為空。原因在于C++中,編譯器對內(nèi)置類型不會做處理(個別如vs2019等編譯器會做處理的),這也就意味這_str是一個隨機(jī)值,指向任意一塊空間。調(diào)用析構(gòu)函數(shù)時會報(bào)錯。

1.4 賦值重載

賦值重載同樣分為傳統(tǒng)寫法和現(xiàn)代寫法。
傳統(tǒng)寫法:

string& operator=(const string& s)
{
	if (this != &s)
	{
		char* tmp = new char[s._capacity + 1];
		strcpy(tmp, s._str);
		delete[] _str;
		_str = tmp;
		_size = s._size;
		_capacity = s._capacity;
	}
	return *this;
}

現(xiàn)代寫法:

//現(xiàn)代寫法
//法一
/*string& operator=(const string& s)
{
	if (this != &s)
	{
		string tmp(s._str);
		swap(tmp);
	}
	return *this;
}*/

//法二
string& operator=(string tmp)
{
	swap(tmp);
	return *this;
}

二、迭代器和范圍for

在C++中,范圍for在底層是通過迭代器來實(shí)現(xiàn)的。所以只要實(shí)現(xiàn)了迭代器,就支持范圍for。
而迭代器類似于指針,迭代器可以被看作是指針的一種泛化,它提供了類似指針的功能,可以進(jìn)行解引用操作、指針運(yùn)算等。
?
以下提供了const迭代器和非const迭代器:

typedef char* iterator;
const typedef char* const_iterator;

	iterator begin()
	{
		return _str;
	}
	iterator end()
	{
		return _str + _size;
	}

	const_iterator begin() const
	{
		return _str;
	}
	const_iterator end() const
	{
		return _str + _size;
	}

三、元素相關(guān):operator[ ]

這里我們和庫中一樣,提供以下兩個版本

//可讀可寫
char operator[](size_t pos)
{
	assert(pos < _size);
	return _str[pos];
}
//只讀
const char operator[](size_t pos)const
{
	assert(pos < _size);
	return _str[pos];
}

四、容量相關(guān):size、resize、capacity、reserve

4.1 size、capacity

size_t size()const
{
	return _size;
}
size_t capacity()const
{
	return _capacity;
}

4.2 reserve

在C++中,我們一般不縮容。
所以實(shí)現(xiàn)reserve時(容量調(diào)整到n),首先判斷目標(biāo)容量n是否大于當(dāng)前容量。如果小于就不做處理,否則先開辟n+1個內(nèi)存空間(多出來的一個用于存儲‘\0’),然后將原有數(shù)據(jù)拷貝到新空間(strcpy會將’\0’一并拷貝過去)。然后釋放就空間,并讓_str指向新空間,同時更新_capacity。

void reserve(size_t n)
{
	if (n > _capacity)
	{
		char* tmp = new char[n + 1];
		strcpy(tmp, _str);
		delete[] _str;
		_str = tmp;
		_capacity = n;
	}
}

4.3 resize

resize到目標(biāo)大小分為以下3中情況:
C++_String增刪查改模擬實(shí)現(xiàn),C++經(jīng)典收錄,c++,java,jvm,c語言,筆記,stl

  1. 當(dāng)n<_size時,只需將下標(biāo)為n的地址處的數(shù)據(jù)改為’\0’。
  2. 其他情況,我們直接統(tǒng)一處理。直接復(fù)用reserve()函數(shù)將_capacity擴(kuò)到n。然后用將[_size, n)中的數(shù)據(jù)全部初始化為ch。(這里博主給ch一個初始值’\0’,但ch不一定為’\0’,所以要將下標(biāo)為n處的地址初始化為’\0’)
void resize(size_t n, char ch='\0')
{
	if (n <= _size)
	{
		_str[n] = '\0';
		_size = n;
	}
	else
	{
		reserve(n);
		while (_size < n)
		{
			_str[_size] = ch;
			_size++;
		}
		_str[_size] = '\0';
	}
}

五、數(shù)據(jù)相關(guān):push_bach、append、operator+=、insert、erase

5.1 尾插:push_back

尾插首先檢查擴(kuò)容,在插入數(shù)據(jù)

void push_back(char ch)
{
	//擴(kuò)容
	if (_size == _capacity)
	{
		reserve(_capacity == 0 ? 4 : _capacity * 2);
	}
	//插入數(shù)據(jù)
	_str[_size] = ch;
	_size++;
	_str[_size] = '\0';

}

5.2 append尾部插入字符串

void append(const char* str)
{
	size_t len = strlen(str);
	if (_size + len > _capacity)//擴(kuò)容
	{
		reserve(_size + len);
	}
	strcpy(_str + _size, str);
	_size += len;
}

5.3 operator+=()字符、字符串

operator+=()字符、字符串可以直接復(fù)用push_back和append。

string& operator+=(char ch)
{
	push_back(ch);
	return *this;
}

string& operator+=(const char* str)
{
	append(str);
	return *this;
}

5.4 insert插入字符、字符串

5.4.1 insert插入字符(在這提醒下,博主是所有的拷貝數(shù)據(jù)都是從’\0’開始,這樣就不需要單獨(dú)對’\0’做處理)

insert插入字符邏輯上還是很簡單的。
首先判斷插入字符時是否需要擴(kuò)容。然后從下標(biāo)為pos開始,所有數(shù)據(jù)依次往后挪動。最后將待插入字符給到pos處即可

初學(xué)者最容易范的一個錯誤

但對于初學(xué)者來說,貌似也不太輕松。。。。。。
下面給出各位初學(xué)者容易犯的錯誤:

void insert(size_t pos, char ch)
{
	assert(pos <= _size);
	//擴(kuò)容
	if (_size == _capacity)
	{
		reserve(_capacity == 0 ? 4 : _capacity * 2);
	}
	//挪動數(shù)據(jù)
	size_t end = _size;
	while (end >= pos)
	{
		_str[end+1] = _str[end];
		end--;
	}
	_str[pos] = ch;
	_size++
}

這樣對嗎?答案是錯誤的。

假設(shè)是在頭插字符,end理論上和pos(即0)比較完后就減到-1,在下一次循環(huán)條件比較時失敗,退出循環(huán)。
遺憾的是end是size_t類型,始終>=0, 會導(dǎo)致死循環(huán)。

博主在這給出兩種解決方法:

  1. 將pos強(qiáng)轉(zhuǎn)為整型。
void insert(size_t pos, char ch)
{
	assert(pos <= _size);
	//擴(kuò)容
	if (_size == _capacity)
	{
		reserve(_capacity == 0 ? 4 : _capacity * 2);
	}
	//挪動數(shù)據(jù)
	int end = _size;
	while (end >= (int)pos)
	{
		_str[end+1] = _str[end];
		end--;
	}
	_str[pos] = ch;
	_size++
}

2.從end從最后數(shù)據(jù)的后一位開始,每次將前一個數(shù)據(jù)移到當(dāng)前位置。最后條件判斷就轉(zhuǎn)化為end>pos,不會出現(xiàn)死循環(huán)這種情況。
C++_String增刪查改模擬實(shí)現(xiàn),C++經(jīng)典收錄,c++,java,jvm,c語言,筆記,stl

void insert(size_t pos, char ch)
{
	assert(pos <= _size);
	//擴(kuò)容
	if (_size == _capacity)
	{
		reserve(_capacity == 0 ? 4 : _capacity * 2);
	}
	//挪動數(shù)據(jù)
	size_t end = _size+1;
	while (end > pos)
	{
		_str[end] = _str[end-1];
		end--;
	}
	//插入數(shù)據(jù),更新_size
	_str[pos] = ch;
	_size++;
}

5.4.2 insert插入字符串

insert同樣存在相同問題,并且思路一樣。博主就直接給出代碼了。
法一:

void insert(size_t pos, const char* str)
{
	int len = strlen(str);
	if (_size + len > _capacity)
	{
		reserve(_size + len);
	}

	int end = _size;
	while (end >= (int)pos)
	{
		_str[end + len] = _str[end];
		end--;
	}
	strncpy(_str + pos, str, len);
	_size += len;
}

法二:

void insert(size_t pos, const char* str)
{
	int len = strlen(str);
	if (_size + len > _capacity)
	{
		reserve(_size + len);
	}
	
	size_t end = _size+1;
	while (end > pos)
	{
		_str[end + len-1] = _str[end-1];
		end--;
	}
	strncpy(_str + pos, str, len);
	_size += len;
}

5.5 erase

erase分兩種情況:

  1. 從pos開始,要刪的數(shù)據(jù)個數(shù)超過的字符串,即將pos后序所有數(shù)據(jù)全部情況。(直接將pos處數(shù)據(jù)置為’\0’即可)
  2. 從pos開始,要刪的數(shù)據(jù)個數(shù)沒有超出的字符串。所以只需要從pos+len位置后的所有數(shù)據(jù)向前移動從pos位置覆蓋原數(shù)據(jù)即可。
void erase(size_t pos, size_t len = npos)
{
	if (len==npos || pos + len >= _size)
	{
		//有多少,刪多少
		_str[pos] = '\0';
		_size = pos;
	}
	else
	{
		size_t begin = pos + len;
		while (begin <= _size)
		{
			_str[begin - len] = _str[begin];
			begin++;
		}
		_size -= len;
	}
}

六、 關(guān)系操作符重載:< 、 ==、 <=、 >、>=、!=

bool operator<(const string& s) const
{
	return strcmp(_str, s._str) < 0;
}

bool operator==(const string& s) const
{
	return strcmp(_str, s._str) == 0;
}

bool operator<=(const string& s) const
{
	return *this < s || *this == s;
}

bool operator>(const string& s) const
{
	return !(*this <= s);
}

bool operator>=(const string& s) const
{
	return !(*this < s);
}

bool operator!=(const string& s) const
{
	return !(*this == s);
}

七、find查找字符、字符串、substr

7.1 find查找字符

size_t find(char ch, size_t pos = 0)
{
	for (size_t i = pos; i < _size; i++)
	{
		if (_str[i] == ch)
		{
			return i;
		}
	}

	return npos;
}

7.2 find查找字符串

size_t find(const char* sub, size_t pos = 0)
{
	const char* p = strstr(_str + pos, sub);
	if (p)
	{
		return p - _str;
	}
	else
	{
		return npos;
	}
}

7.3 strsub( ) 模擬實(shí)現(xiàn)

strsub目標(biāo)長度可能越界string,也可能還有沒有。但不管是那種情況,最后都需要拷貝數(shù)據(jù)。所以這里我們可以先將len真實(shí)長度計(jì)算出來,在拷貝數(shù)據(jù)。

string substr(size_t pos, size_t len = npos)const
{
	string s;
	size_t end = pos + len;
	//目標(biāo)字符越界string,更新len
	if (len == npos || end >= _size)
	{
		len = _size - pos;
		end = _size;
	}
	
	//拷貝數(shù)據(jù)
	s.reserve(len);
	for (size_t i = pos; i < end; i++)
	{
		s += _str[i];
	}

	return s;
}

八、流插入和流提?。?lt;<、>>)(實(shí)現(xiàn)在string類外)

8.1 流插入<<

由于前面我們實(shí)現(xiàn)了迭代器,所以最簡單的方式就是范圍for

ostream& operator<<(ostream& out, const string& s)
{
	/*for (size_t i = 0; i < s.size(); i++)
	{
		out << s[i];
	}*/
	for (auto ch : s)
		out << ch;

	return out;
}

8.1 流提取>>

流提取比較特殊。在流提取前需要將原有數(shù)據(jù)全部清空。同時由于>>無法獲取空字符和換行符()(都是作為多個值之間的間隔),直接流提取到ostream對象中,沒法結(jié)束。(類似于C語言中scanf, 換行符和空字符僅僅只是起到判斷結(jié)束的作用,但scanf無法獲取到它們)
所以這里博主直接調(diào)用istream對象中的get()函數(shù)。(類似于C語言中的getchar()函數(shù))
get詳細(xì)文檔
C++_String增刪查改模擬實(shí)現(xiàn),C++經(jīng)典收錄,c++,java,jvm,c語言,筆記,stl

class string
{
	void clear()
	{
		_str[0] = '\0';
		_size = 0;
	}
private:
	char* _str;
	size_t _capacity;
	size_t _size;
};

istream& operator>>(istream& in, string& s)
	{
		s.clear();
		char ch;
		//in >> ch;
		ch = in.get();

		while (ch != ' ' && ch != '\n')
		{
			s += ch;
			//in >> ch;
			ch = in.get();
		}
		return in;
	}

上面這種方法雖然可以達(dá)到目的。但還有一個問題,每次插入數(shù)據(jù)都面臨可擴(kuò)容問題。那如何優(yōu)化呢?

優(yōu)化

其中一種辦法就是調(diào)用reserve()提前開好空間,但這樣面臨這另一個問題:開大了浪費(fèi)空間;開小了,同樣面臨這擴(kuò)容的問題。
所以在這博主采用和vs底層實(shí)現(xiàn)的思路:首先開好一段數(shù)組(包含’\0’,以16為例)。當(dāng)數(shù)據(jù)個數(shù)小于16時,字符串存在數(shù)組中;當(dāng)數(shù)據(jù)個數(shù)大于等于16時,將數(shù)據(jù)存在_str指向的空間。
這是一種以空間換時間的思路,同時也能很好的減少內(nèi)存碎片的問題。
文章來源地址http://www.zghlxwxcb.cn/news/detail-757945.html

class string
{
	void clear()
	{
		_str[0] = '\0';
		_size = 0;
	}
private:
	char* _str;
	size_t _capacity;
	size_t _size;
};

istream& operator>>(istream& in, string& s)
{
	s.clear();

	char buff[16];
	size_t i = 0;

	char ch;
	ch = in.get();
	while (ch != ' ' && ch != '\n')
	{
		buff[i++] = ch;
		if (i == 16)
		{
			buff[i] = '\0';
			s += buff;
			i = 0;
		}
	ch = in.get();
	}

	if (i != 0)
	{
		buff[i] = '\0';
		s += buff;
	}
	return in;
}

九、所有代碼

namespace achieveString
{
	class string
	{
	public:
	typedef char* iterator;
	const typedef char* const_iterator;

	iterator begin()
	{
		return _str;
	}
	iterator end()
	{
		return _str + _size;
	}

	const_iterator begin() const
	{
		return _str;
	}
	const_iterator end() const
	{
		return _str + _size;
	}

		//構(gòu)造函數(shù)
		/*string()
			:_str(new char[1]{'\0'})
			,_capacity(0)
			,_size(0)
		{ }*/
		string(const char* str = "")
			:_capacity(strlen(str))
			, _size(_capacity)
		{
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}

		const char* c_str() const
		{
			return _str;
		}

		//析構(gòu)函數(shù)
		~string()
		{
			delete[] _str;
			_str = nullptr;
			_size = _capacity = 0;
		}

		//拷貝構(gòu)造
		/*string(const string& s)
		{
			_str = new char[s._capacity + 1];
			strcpy(_str, s._str);
			_size = s._size;
			_capacity = s._capacity;
		}*/

		//交換
		void swap(string& s)
		{
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}

		//現(xiàn)代寫法
		string(const string& s)
			:_str(nullptr)
			,_size(0)
			,_capacity(0)
		{
			string tmp(s._str);
			swap(tmp);
		}

		// 賦值重載
		/*string& operator=(const string& s)
		{
			if (this != &s)
			{
				char* tmp = new char[s._capacity + 1];
				strcpy(tmp, s._str);
				delete[] _str;
				_str = tmp;
				_size = s._size;
				_capacity = s._capacity;
			}
			return *this;
		}*/
		//現(xiàn)代寫法
		//法一
		/*string& operator=(const string& s)
		{
			if (this != &s)
			{
				string tmp(s._str);
				swap(tmp);
			}
			return *this;
		}*/
		//法二
		string& operator=(string tmp)
		{
			swap(tmp);
			return *this;
		}

		//可讀可寫
		char operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}
		//只讀
		const char operator[](size_t pos)const
		{
			assert(pos < _size);
			return _str[pos];
		}

		size_t size()const
		{
			return _size;
		}
		size_t capacity()const
		{
			return _capacity;
		}

		bool empty()const
		{
			return _size == 0;
		}

		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];
				strcpy(tmp, _str);
				delete[] _str;
				_str = tmp;
				_capacity = n;
			}
		}

		void resize(size_t n, char ch='\0')
		{
			if (n <= _size)
			{
				_str[n] = '\0';
				_size = n;
			}
			else
			{
				reserve(n);
				while (_size < n)
				{
					_str[_size] = ch;
					_size++;
				}
				_str[_size] = '\0';
			}
		}

		void push_back(char ch)
		{
			//擴(kuò)容
			if (_size == _capacity)
			{
				reserve(_capacity == 0 ? 4 : _capacity * 2);
			}
			//插入數(shù)據(jù)
			_str[_size] = ch;
			_size++;
			_str[_size] = '\0';
		
		}

		void append(const char* str)
		{
			size_t len = strlen(str);
			if (_size + len > _capacity)
			{
				reserve(_size + len);
			}
			strcpy(_str + _size, str);
			_size += len;
		}

		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}

		string& operator+=(const char* str)
		{
			append(str);
			return *this;
		}
		
		void insert(size_t pos, char ch)
		{
			assert(pos <= _size);
			//擴(kuò)容
			if (_size == _capacity)
			{
				reserve(_capacity == 0 ? 4 : _capacity * 2);
			}
			//挪動數(shù)據(jù)
			size_t end = _size+1;
			while (end > pos)
			{
				_str[end] = _str[end-1];
				end--;
			}
			//插入數(shù)據(jù),更新_size
			_str[pos] = ch;
			_size++;
		}
		void insert(size_t pos, const char* str)
		{
			int len = strlen(str);
			if (_size + len > _capacity)
			{
				reserve(_size + len);
			}

			//法一
			/*int end = _size;
			while (end >= (int)pos)
			{
				_str[end + len] = _str[end];
				end--;
			}
			strncpy(_str + pos, str, len);
			_size += len;*/

			//法二
			size_t end = _size+1;
			while (end > pos)
			{
				_str[end + len-1] = _str[end-1];
				end--;
			}
			strncpy(_str + pos, str, len);
			_size += len;
		}

		void erase(size_t pos, size_t len = npos)
		{
			if (len==npos || pos + len >= _size)
			{
				//有多少,刪多少
				_str[pos] = '\0';
				_size = pos;
			}
			else
			{
				size_t begin = pos + len;
				while (begin <= _size)
				{
					_str[begin - len] = _str[begin];
					begin++;
				}
				_size -= len;
			}
		}
		bool operator<(const string& s)const
		{
			return strcmp(_str, s._str) < 0;
		}

		bool operator==(const string& s)const
		{
			return strcmp(_str, s._str) == 0;
		}

		bool operator<=(const string& s)const
		{
			return *this == s && *this < s;
		}

		bool operator>(const string& s)const
		{
			return !(*this <= s);
		}

		bool operator>=(const string& s)const
		{
			return !(*this < s);
		}

		bool operator!=(const string& s)const
		{
			return !(*this == s);
		}

		size_t find(char ch, size_t pos = 0)
		{
			for (size_t i = pos; i < _size; i++)
			{
				if (_str[i] == ch)
					return i;
			}
			return npos;
		}

		size_t find(const char* sub, size_t pos = 0)
		{
			const char* p = strstr(_str + pos, sub);
			if (p)
			{
				return p - _str;
			}
			else
			{
				return npos;
			}
		}

		string substr(size_t pos, size_t len = npos)
		{
			string s;
			size_t end = pos + len;
			if (len == npos || end >= _size)
			{
				len = _size - pos;
				end = _size;
			}
			
			s.reserve(len);
			for (size_t i = pos; i < end; i++)
			{
				s += _str[i];
			}

			return s;
		}
		void clear()
		{
			_str[0] = '\0';
			_size = 0;
		}
	private:
		char* _str;
		size_t _capacity;
		size_t _size;

		//const static size_t npos = -1;  // C++支持const整型靜態(tài)變量在聲明時給值初始化,但不建議
		//const static double npos = 1.1;  // 不支持

		const static size_t npos;
	};
	const size_t string::npos = -1;

	ostream& operator<<(ostream& out, const string& s)
	{
		/*for (size_t i = 0; i < s.size(); i++)
		{
			out << s[i];
		}*/
		for (auto ch : s)
			out << ch;

		return out;
	}

	//istream& operator>>(istream& in, string& s)
	//{
	//	s.clear();
	//	char ch;
	//	//in >> ch;
	//	ch = in.get();

	//	while (ch != ' ' && ch != '\n')
	//	{
	//		s += ch;
	//		//in >> ch;
	//		ch = in.get();
	//	}
	//	return in;
	//}

	istream& operator>>(istream& in, string& s)
	{
		s.clear();

		char buff[16];
		size_t i = 0;

		char ch;
		ch = in.get();
		while (ch != ' ' && ch != '\n')
		{
			buff[i++] = ch;
			if (i == 16)
			{
				buff[i] = '\0';
				s += buff;
				i = 0;
			}
			ch = in.get();
		}

		if (i != 0)
		{
			buff[i] = '\0';
			s += buff;
		}

		return in;
	}
}

到了這里,關(guān)于C++_String增刪查改模擬實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • C++:list增刪查改模擬實(shí)現(xiàn)

    C++:list增刪查改模擬實(shí)現(xiàn)

    本篇博客采用SGI版本,同時考慮到看到此篇博客大部分為初學(xué)者,為此博主僅僅給出有用片段。 C++:list增刪查改模擬實(shí)現(xiàn)就是用C++復(fù)寫雙鏈表,非常簡單。難點(diǎn)主要在迭代器實(shí)現(xiàn) list底層使用什么數(shù)據(jù)結(jié)構(gòu)來實(shí)現(xiàn)的呢?我們先來看看SGI庫中l(wèi)ist的成員函數(shù)和初始化吧。 我們發(fā)現(xiàn)

    2024年02月04日
    瀏覽(19)
  • 【C++】vector類的模擬實(shí)現(xiàn)(增刪查改,拷貝構(gòu)造,賦值運(yùn)算,深淺拷貝)

    【C++】vector類的模擬實(shí)現(xiàn)(增刪查改,拷貝構(gòu)造,賦值運(yùn)算,深淺拷貝)

    ??博客主頁: 主頁 ??系列專欄: C++ ??感謝大家點(diǎn)贊??收藏?評論?? ??期待與大家一起進(jìn)步! 我們模擬vector是用迭代器(start,end,endofstorage)來控制增刪查改操作的 1普通構(gòu)造 2迭代器構(gòu)造 3初始化字符構(gòu)造 4拷貝構(gòu)造: 1當(dāng)前大小(size()) 2總體容量(capacity()) 1begin()

    2024年02月15日
    瀏覽(20)
  • 【C++】STL——list的模擬實(shí)現(xiàn)、構(gòu)造函數(shù)、迭代器類的實(shí)現(xiàn)、運(yùn)算符重載、增刪查改

    【C++】STL——list的模擬實(shí)現(xiàn)、構(gòu)造函數(shù)、迭代器類的實(shí)現(xiàn)、運(yùn)算符重載、增刪查改

    list使用文章 析構(gòu)函數(shù) ??在定義了一個類模板list時。我們讓該類模板包含了一個內(nèi)部結(jié)構(gòu)體_list_node,用于表示鏈表的節(jié)點(diǎn)。該結(jié)構(gòu)體包含了指向前一個節(jié)點(diǎn)和后一個節(jié)點(diǎn)的指針以及節(jié)點(diǎn)的值。在list中保存了鏈表的頭節(jié)點(diǎn)指針和鏈表長度大小。 ? ? ??因?yàn)閘ist的底層實(shí)現(xiàn)

    2024年02月14日
    瀏覽(27)
  • C++:stack、queue、priority_queue增刪查改模擬實(shí)現(xiàn)、deque底層原理

    C++:stack、queue、priority_queue增刪查改模擬實(shí)現(xiàn)、deque底層原理

    我們先來看看 stack的相關(guān)接口有哪些: 從棧的接口,我們可以知道棧的接口是一種特殊的vector,所以我們完全可以使用vector來模擬實(shí)現(xiàn)stack。 因此我們可以將底層容器定義成模板,然后將容器類變量作為成員變量進(jìn)行封裝。在實(shí)現(xiàn)satck的各種接口時,通過成員變量來調(diào)用底層

    2024年02月03日
    瀏覽(24)
  • Elasticsearch基礎(chǔ)學(xué)習(xí)(Java API 實(shí)現(xiàn)增刪查改)

    Elasticsearch基礎(chǔ)學(xué)習(xí)(Java API 實(shí)現(xiàn)增刪查改)

    ElasticSearch,簡稱為ES, ES是一個開源的高擴(kuò)展的分布式全文搜索引擎。它可以近乎實(shí)時的存儲、檢索數(shù)據(jù);本身擴(kuò)展性很好,可以擴(kuò)展到上百臺服務(wù)器,處理PB級別的數(shù)據(jù)。 物理設(shè)計(jì): ElasticSearch 在后臺把每個索引劃分成多個分片,每份分片可以在集群中的不同服務(wù)器間遷移

    2024年02月01日
    瀏覽(38)
  • 認(rèn)識Mybatis并實(shí)現(xiàn)增刪查改

    認(rèn)識Mybatis并實(shí)現(xiàn)增刪查改

    目錄 一.Mybatis特性 二.常見持久層技術(shù)的比較 三.搭建Mybaits環(huán)境 四.使用Mybatis ?五.通過Mybatis實(shí)現(xiàn)增刪改 ?六.實(shí)現(xiàn)數(shù)據(jù)庫的查詢操作 定制化SQL:MyBatis允許開發(fā)人員編寫、優(yōu)化和管理自定義的SQL語句,可以滿足復(fù)雜查詢和存儲過程等高級操作的需求。 避免JDBC代碼:MyBatis抽象了

    2024年02月12日
    瀏覽(17)
  • java springboot整合MyBatis演示增刪查改操作

    java springboot整合MyBatis演示增刪查改操作

    前面我的文章 java springboot整合MyBatis做數(shù)據(jù)庫查詢操作講述了整合springboot整合MyBatis 做了根據(jù)id查詢的語句 那么 我們現(xiàn)在按它搭建的項(xiàng)目繼續(xù) 我們在staffDao中添加一個insert函數(shù) 參考代碼如下 Insert需要手動導(dǎo)包 import org.apache.ibatis.annotations.Insert; 這就是一個添加語句函數(shù) 返回一

    2024年02月11日
    瀏覽(30)
  • 帶頭 + 雙向 + 循環(huán)鏈表增刪查改實(shí)現(xiàn)

    帶頭 + 雙向 + 循環(huán)鏈表增刪查改實(shí)現(xiàn)

    目錄 源碼: List.c文件: List.h文件: 簡單的測試: 很簡單,沒什么好說的,直接上源碼。

    2024年01月23日
    瀏覽(17)
  • C語言—實(shí)現(xiàn)循序表的增刪查改

    C語言—實(shí)現(xiàn)循序表的增刪查改

    嗨嗨嗨!大家好!今天我為大家分享的是數(shù)據(jù)結(jié)構(gòu)知識——順序表。廢話不多數(shù),讓我們開始今天的知識分享吧。 數(shù)據(jù)結(jié)構(gòu)是計(jì)算機(jī)存儲、組織數(shù)據(jù)的方式。數(shù)據(jù)結(jié)構(gòu)是指相互之間存在一種或多種特定關(guān)系的數(shù)據(jù)元素的集合。數(shù)據(jù)結(jié)構(gòu)反映數(shù)據(jù)的內(nèi)部構(gòu)成,即數(shù)據(jù)由那部分構(gòu)

    2024年04月15日
    瀏覽(13)
  • 【數(shù)據(jù)結(jié)構(gòu)】單鏈表的增刪查改(C實(shí)現(xiàn))

    【數(shù)據(jù)結(jié)構(gòu)】單鏈表的增刪查改(C實(shí)現(xiàn))

    優(yōu)勢 : 可通過 下標(biāo)i (數(shù)據(jù)連續(xù)(物理空間連續(xù))) 便捷查詢查找順序表中的信息,也會在后面的 排序算法 和 堆算法 中盡顯身手 問題 : 在頭部/中間的插入與刪除需要 挪動數(shù)據(jù) ,時間復(fù)雜度為O(N),效率低; 增容需要申請新空間, 可能會拷貝數(shù)據(jù) ,釋放舊空間,會有

    2024年02月05日
    瀏覽(94)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包