c++(vector)

“vector字典”

约等于顺序表

reserve

小于size,不会缩容

resize 

会缩容,空间不够会用给的缺省值初始化新构造的数字

insert(支持迭代器)

不支持流插入,流提取

隐式类型转换

std::string 可以接受 const char* 类型的参数,从而实现这种隐式类型转换

二维数组实现

118. 杨辉三角

class Solution {
public:
    vector<vector<int>> generate(int numRows) {
        vector<vector<int>> vv(numRows);
        for(int i=0;i<numRows;i++)
        {
            vv[i].resize(i+1,1);
        }

        for(int i=2;i<numRows;i++)
        {
            for(int j=1;j<i;j++)
            {
                vv[i][j]=vv[i-1][j-1]+vv[i-1][j];
            }
        }
        return vv;
    }
};

代码实现

迭代器失效:

1.会引起其底层空间改变的操作,都有可能是迭代器失效,比如:resize、reserve、insert、
   assign、push_back等

insert,空间不够需要扩容,reserve,需要记录原先的size(),扩容后,原先的空间被释放

                                                         

2. 指定位置元素的删除操作--erase

如果pos刚好是最后一个元素,删完之后pos刚好是end的位置,而end位置是没有元素的,那么pos就失效了。因此删除vector中任意位置上元素时,vs就认为该位置迭代器失效了

库里erase需要更新it的位置,因为删除的同时it在移动,end()也在减小,不更新it,会造成死循环 

3. 注意:Linux下,g++编译器对迭代器失效的检测并不是非常严格,处理也没有vs下极端。
4. 与vector类似,string在插入+扩容操作+erase之后,迭代器也会失效
迭代器失效解决办法:在使用前,对迭代器重新赋值即可

memcpy拷贝问题


1. memcpy是内存的二进制格式拷贝,将一段内存空间中内容原封不动的拷贝到另外一段内存
空间中
2. 如果拷贝的是自定义类型的元素,memcpy既高效又不会出错,但如果拷贝的是自定义类型
元素,并且自定义类型元素中涉及到资源管理时,就会出错,因为memcpy的拷贝实际是浅拷贝

vector.h

#pragma once
#include"iostream"
#include"assert.h"
#include<algorithm>
using namespace std;
namespace bit
{
	template<class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef const T* const_iterator; 
		size_t size() const
		{
			return _finish - _start;
		}
		size_t capacity() const
		{
			return _end_of_storage - _start;
		}
		bool empty(const vector<int>& v)
		{
			return _start == _finish;
		}
		void pop_back(const vector<int>& v)
		{
			assert(!empty(v));
			--_finish;
		}

		void print_vector(const vector<int>& v)
		{
			vector<int>::const_iterator it = v.begin();
			while (it != v.end())
			{
				cout << *it << " ";
				it++;
			}
			cout << endl;

			for (auto e : v)
			{
				cout << e << " ";
			}
			cout << endl;
		}
		iterator begin()
		{
			return _start;
		}
		iterator end()
		{
			return _finish;
		}

		const_iterator begin()const
		{
			return _start;
		}
		const_iterator end() const
		{
			return _finish;
		}

		void reserve(size_t n)
		{
			if (n > capacity())
			{
				size_t old_size = size();
				T* tmp = new T[n];				
				//浅拷贝
				//memcpy(tmp, _start, size() * sizeof(T));
				//调用string深拷贝
				for (int i = 0; i < old_size; i++)
				{
					tmp[i] = _start[i];
				}
				delete[]_start;
				_start = tmp;
				_finish = tmp + old_size;
				_end_of_storage = tmp + n;
			}
		}

		void push_back(const T& x)
		{
			if (_finish == _end_of_storage)
			{
				reserve(capacity() == 0 ? 4 : capacity() * 2);
			}
			*_finish = x;
			++_finish;
		}

		//迭代器失效
		iterator insert(iterator pos, const T& x)
		{
			assert(pos >= _start);
			assert(pos <= _finish);

			if (_finish == _end_of_storage)
			{
				size_t len = pos - _start;
				reserve(capacity() == 0 ? 4 : capacity() * 2);
				pos = _start + len;
			}
			iterator end = _finish - 1;
			while (end >= pos)
			{
				*(end + 1) = *end;
				--end;
			}
			*pos = x;

			++_finish;
			return pos;
		}

		void erase(iterator pos)
		{
			assert(pos >= _start);
			assert(pos < _finish);
			 
			iterator it = pos + 1;
			while (it != end())
			{
				*(it - 1) = *it;
				++it;
			}
			--_finish;
		}

		void resize(size_t n, T val = T())
		{
			if (n < size())
			{
				_finish = _start + n;
			}
			else
			{
				reserve(n);
				while (_finish < _start + n)
				{
					*_finish = val;
					++_finish;
				}
			}
		}
		T& operator[](size_t i)
		{
			assert(i < size());
			return _start[i];
		}
		const T& operator[](size_t i) const
		{
			assert(i < size());
			return _start[i];
		}

		//类模板的成员函数,还可以继续是函数模板
		template <class InputIterator>
		vector(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				push_back(*first);
				++first;
			}
		}

		/*vector(size_t n, const T& val = T())
		{
			reserve(n);
			for (size_t i = 0; i < n; i++)
			{
				push_back(val);
			}
		}*/

		vector(int n, const T& val = T())
		{
			reserve(n);
			for (int i = 0; i < n; i++)
			{
				push_back(val);
			}
		}

		void clear()
		{
			_finish = _start;
		}

		//赋值拷贝
		vector<int>& operator=(const vector<int>& v)
		{
			if (this != &v)
			{
				clear();
				reserve(v.size());
				for (auto& e : v)
				{
					push_back(e);
				}
			}
			return *this;
		}
		
		void swap(vector<int>& v)
		{
			std::swap(_start, v._start);
			std::swap(_finish, v._finish);
			std::swap(_end_of_storage, v._end_of_storage);
		}

		//类里可以用类名替代类型
		vector& operator=(vector<T> v)
		//vector<T>& operator=(vector<T> v)
		{
			swap(v);

			return *this;
		}

		
		//构造函数
		/*vector()
		{}*/

		//强制生成默认构造 c++11
		vector() = default;

		//拷贝构造
		vector(const vector<int>& v)
		{
			reserve(v.size());
			for (auto& e : v)
			{
				push_back(e);
			}
		}


		~vector()
		{
			if (_start)
			{
				delete[]_start;
				_start = _finish = _end_of_storage = nullptr;
			}
		}
	private:
		iterator _start = nullptr;
		iterator _finish = nullptr;
		iterator _end_of_storage = nullptr;
	};
	/*void print_vector(const vector<int>& v)
	{
		vector<int>::const_iterator it = v.begin();
		while (it != v.end())
		{
			cout << *it << " ";
			it++;
		}
		cout << endl;
		for (auto e : v)
		{
			cout << e << " ";
		}
		cout << endl;
	}*/

	template<class T>
	void print_vector(const vector<T>& v)
	{
		//规定,没有实例化的类模板里面取东西,编译器不能区分这里const_iterator
		//是类型还是静态成员变量
		typename vector<T>::const_iterator it = v.begin();
		while (it != v.end())
		{
			cout << *it << " ";
			it++;
		}
		cout << endl;
		for (auto e : v)
		{
			cout << e << " ";
		}
		cout << endl;
	}
	
	template<class Container>
	void print_container(const Container& v)
	{
		//规定,没有实例化的类模板里面取东西,编译器不能区分这里const_iterator
		//是类型还是静态成员变量
		//typename Container::const_iterator it = v.begin();
		auto it = v.begin();
		while (it != v.end())
		{
			cout << *it << " ";
			it++;
		}
		cout << endl;
		/*for (auto e : v)
		{
			cout << e << " ";
		}
		cout << endl;*/
	}
	 
	void test_vector()
	{
		/*std::vector<int> v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(5); */

		//for (size_t i = 0; i < v.size(); i++)
		//{
		//	cout << v[i] << " ";
		//}
		//cout << endl;
		insert不能引用,临时变量具有常性,会造成权限放大
		//v.insert(v.begin() + 2, 30);
		//print_container(v);

		v.print_vector(v);
		print_vector(v);
		// 
		//int x = 0;
		//cin >> x;
		//auto pos = find(v.begin(), v.end(), x);
		//if (pos != v.end())
		//{
		//	//insert后迭代器pos失效,不要访问
		//	//v1.insert(pos, 30.1);


		//	//insert以后p就是失效,不要直接访问,要访问就要更新这个失效的迭代器的值
		//	pos = v.insert(pos, 40);
		//	(*(pos + 1)) *= 10;



		//	报错,位置未更新
		//	//v.insert(pos, 2);
		//	//(*pos) *= 10;


		//	
		//}


		vector<int> v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(4);
		v.push_back(4);
		v.push_back(5);
		v.push_back(5);
		v.push_back(5);
		v.push_back(4);
		auto it = v.begin();
		while (it != v.end())
		{
			if (*it % 2 == 0)
			{
				v.erase(it);
			}
			else
			{
				it++;
			}
		}
		print_container(v);

		//vector<double> v1;
		//v1.push_back(1.1);
		//v1.push_back(2.1);
		//v1.push_back(3.1);
		//v1.push_back(4.1);
		//print_vector(v1);
		//
		//int x = 0;
		//cin >> x;
		//auto pos = find(v.begin(), v.end(),x);
		//if (pos != v.end())
		//{
		//	//insert后迭代器pos失效,不要访问
		//	//v1.insert(pos, 30.1);

		//	pos = v.insert(pos, 40.1);
		//	(*(pos + 1)) *= 10;
		//}
		//print_vector(v1);

	}

	void test_vector1()
	{
		vector<int> v;//默认构造函数
		/*v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);*/
		v.resize(10,1);
		print_vector(v);
		v.resize(15, 200);
		print_vector(v);
		v.reserve(5);
		print_vector(v);
		v.resize(5);
		print_vector(v);
	}

	//void test_vector2()
	//{
	//	vector<int> v;
	//	v.push_back(1);
	//	v.push_back(2);
	//	v.push_back(3);
	//	v.push_back(4);
	//	vector<int> v1(v);
	//	print_vector(v1); 

	//	vector<int> v3 = v1;
	//	print_vector(v3);
	//}

	void test_vector3()
	{

		/*vector<int> v2(10u, 1);
		print_container(v2);*/

		vector<int> v1(10,1);
		print_container(v1);

		
	}

	void test_vector4()
	{
		//扩容造成的失败
		vector<string> v1;
		v1.push_back("1111111111111111111");
		v1.push_back("1111111111111111111");
		v1.push_back("1111111111111111111");
		v1.push_back("1111111111111111111");
		print_container(v1);
		v1.push_back("1111111111111111111");
		v1.push_back("1111111111111111111");
		v1.push_back("1111111111111111111");
		v1.push_back("1111111111111111111");
		print_container(v1);

	}
}

test.cpp

 #include"iostream"
#include"vector"
using namespace std;

void test_i()
{

	//构造函数
	vector<int> v1;
	vector<int> v2(10, 1);
	vector<int> v3(++v2.begin(), --v2.end());
	//便历下标
	for (size_t i = 0; i < v3.size(); i++)
	{
		cout << v3[i] << " ";
	}
	cout << endl;

	vector<int>::iterator it = v3.begin();
	while (it != v3.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;

	for (auto e : v3)
	{
		cout << e << " ";
	}
}
void test_vector()
{
	// 测试vector的默认扩容机制
	size_t sz;
	vector<int> v;
	sz = v.capacity();
	cout << "making v grow:" << sz << endl;
	for (int i = 0; i < 100; ++i)
	{
		v.push_back(i);
		if (sz != v.capacity())
		{
			sz = v.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}

}
void test_string32()
{
	char str8[] = "牛马";//默认
	cout << sizeof(str8) << endl;//两个汉字加'\0'
	cout << str8 << endl;
	char16_t str16[] = u"牛马";//2个字节为单位
	cout << sizeof(str16) << endl;//任何一个符号最少占两个字节
	cout << str16 << endl;
	char32_t str32[] = U"牛马";//4个字节为单位
	cout << sizeof(str32) << endl;
	cout << str32 << endl;
	wchar_t wstr[] = L"牛马";
	cout << sizeof(wstr) << endl;
	cout << wstr << endl;
}
void test_vector1()
{
	vector<int> v1(10, 1);
	cout << v1.size() << endl;
	cout << v1.capacity() << endl;

	v1.reserve(10);
	cout << v1.size() << endl;
	cout << v1.capacity() << endl;

	v1.reserve(5);
	cout << v1.size() << endl;
	cout << v1.capacity() << endl;

	v1.reserve(20);
	cout << v1.size() << endl;
	cout << v1.capacity() << endl;
}
void test_vector2()
{
	vector<int> v1(10, 1);
	cout << v1.size() << endl;
	cout << v1.capacity() << endl;

	v1.resize(10);
	cout << v1.size() << endl;
	cout << v1.capacity() << endl;

	v1.resize(5);
	cout << v1.size() << endl;
	cout << v1.capacity() << endl;

	v1.resize(20);
	cout << v1.size() << endl;
	cout << v1.capacity() << endl;
}
void test_vector3()
{
	/*vector<int> v1(10, 1);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
	v1.push_back(20);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
	v1.insert(v1.begin(), 100);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;*/
	vector<int> v1(5, 1);
	for (size_t i = 0; i < 5; i++)
	{
		cin >> v1[i];
	}
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;

}
void test_vector4()
{
//	vector<string> v1;
//	v1.push_back("yyyyyy");//const char* 隐式类型转换为string
//	//for (auto e : v1)//传值传参会调用拷贝构造,string类,消耗大
//	//{
//	//	cout << e << " ";
//	//	
//	//}
//	//cout << endl;
//
//	for (const auto& e : v1)
//	{
//		cout << e << " ";
//
//	}
//	cout << endl;

	//二维数组
	//10*5
	vector<int> v(5, 1);
	vector<vector<int>> vv(10,v);
	vv[2][1] = 100;
}
//int main()
//{
//	//test_string32();
//	//test_i();
//
//	//reserve
//	//test_vector();
//	//test_vector1();
//	//test_vector2();
//	//test_vector3();
//	test_vector4();
//}


#include"vector.h"
int main()
{
	bit::test_vector();
	//bit::test_vector1();
	//bit::test_vector2();
	//bit::test_vector3();
	//bit::test_vector4();
}



namespace bit

{

  template<class T>

  class vector

  {

  public:

    // Vector的迭代器是一个原生指针

    typedef T* iterator;

    typedef const T* const_iterator;

    iterator begin()

    {

      return _start;

    }

    iterator end()

    {

      return _finish;

    }

    const_iterator cbegin()const

    {

      return _start;

    }

    const_iterator cend() const

    {

      return _finish;

    }



    // construct and destroy

    vector(): _start(nullptr), _finish(nullptr), _endOfStorage(nullptr)

    {}

    vector(int n, const T& value = T())

      : _start(nullptr), _finish(nullptr),_endOfStorage(nullptr)

    {

      reserve(n);

      while (n--)

      {

        push_back(value);

      }

    }

    template<class InputIterator>

    vector(InputIterator first, InputIterator last)

    {

      reserve(last - first);

      while (first != last)

      {

        push_back(*first);

        ++first;

      }

    }

    vector(const vector<T>& v)

      : _start(nullptr), _finish(nullptr), _endOfStorage(nullptr)

    {

      reserve(v.capacity());

      iterator it = begin();

      const_iterator vit = v.cbegin();

      while (vit != v.cend())

      {

      	*it++ = *vit++;

      }

      _finish = _start + v.size();

      _endOfStorage = _start + v.capacity();

    }

    vector<T>& operator= (vector<T> v)

    {

      swap(v);

      return *this;

    }

    ~vector()

    {

      delete[] _start;

      _start = _finish = _endOfStorage = nullptr;

    }

    // capacity

    size_t size() const 

    {

      return _finish - _start;

    }

    size_t capacity() const

    {

      return _endOfStorage - _start;

    }

    void reserve(size_t n)

    {

      if (n > capacity())

      {

        size_t oldSize = size();

        T* tmp = new T[n];

        if (_start)

        {

          for (size_t i = 0; i < oldSize; ++i)

          tmp[i] = _start[i];

        }

        _start = tmp;

        _finish = _start + size;

        _endOfStorage = _start + n;

      }

    }

    void resize(size_t n, const T& value = T())

    {

      // 1.如果n小于当前的size,则数据个数缩小到n

      if (n <= size())

      {

        _finish = _start + n;

        return;

      }

      // 2.空间不够则增容

      if (n > capacity())

      	reserve(n);

      // 3.将size扩大到n

      iterator it = _finish;

      iterator _finish = _start + n;

      while (it != _finish)

      {

        *it = value;

        ++it;

      }

    }



    ///access///

    T& operator[](size_t pos)

    {

      return _start[pos];

    }

    const T& operator[](size_t pos)const

    {

      return _start[pos];

    }



    ///modify/

    void push_back(const T& x)

    {

      insert(end(), x);

    }

    void pop_back()

    {

      erase(--end());

    }

    void swap(vector<T>& v)

    {

      swap(_start, v._start);

      swap(_finish, v._finish);

      swap(_endOfStorage, v._endOfStorage);

    }

    iterator insert(iterator pos, const T& x)

    {

      assert(pos <= _finish);

      // 空间不够先进行增容

      if (_finish == _endOfStorage)

      {

        size_t size = size();

        size_t newCapacity = (0 == capacity())? 1 : capacity() * 2;

        reserve(newCapacity);

        // 如果发生了增容,需要重置pos

        pos = _start + size;

      }

      iterator end = _finish - 1;

      while (end >= pos)

      {

        *(end + 1) = *end;

        --end;

      }

      *pos = x;

      ++_finish;

      return pos;

    }

    // 返回删除数据的下一个数据

		// 方便解决:一边遍历一边删除的迭代器失效问题

    iterator erase(Iterator pos)

    {

      // 挪动数据进行删除

      iterator begin = pos + 1;

      while (begin != _finish) 

      {

        *(begin - 1) = *begin;

        ++begin;

      }

      --_finish;

      return pos;

    }

  private:

    iterator _start; // 指向数据块的开始

    iterator _finish; // 指向有效数据的尾

    iterator _endOfStorage; // 指向存储容量的尾

  };

}

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值