0
点赞
收藏
分享

微信扫一扫

用ffmpeg删除视频的音轨,让视频静音

白衣蓝剑冰魄 2023-10-09 阅读 35

一、list的介绍及使用

https://cplusplus.com/reference/list/list/?kw=list


1、list的使用


(1)list的构造

// list的构造
void TestList1()
{
    list<int> l1;                        // 构造空的l1
    list<int> l2(4, 100);                // l2中放4个值为100的元素
    list<int> l3(l2.begin(), l2.end());  // 用l2的[begin(), end())左闭右开的区间构造l3
    list<int> l4(l3);                    // 用l3拷贝构造l4

    // 以数组为迭代器区间构造l5
    int array[] = {16, 2, 77, 29};
    list<int> l5(array, array + sizeof(array) / sizeof(int));

    // 列表格式初始化C++11
    list<int> l6{1, 2, 3, 4, 5};

    // 用迭代器方式打印l5中的元素
    list<int>::iterator it = l5.begin();
    while (it != l5.end())
    {
        cout << *it << " ";
        ++it;
    }
    cout << endl;

    // C++11范围for的方式遍历
    for (auto& e : l5)
    {
        cout << e << " ";
    }
    cout << endl;
}

(2)list iterator的使用

// list迭代器的使用
void PrintList(const list<int>& l)
{
    // 注意这里调用的是list的 begin() const,返回list的const_iterator对象
    for (list<int>::const_iterator it = l.begin(); it != l.end(); ++it)
    {
        cout << *it << " ";
        // *it = 10; // 不能改变该值 -- 编译不通过
    }
    cout << endl;
}
void TestList2()
{
    int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
    list<int> l(array, array + sizeof(array) / sizeof(array[0]));
    // 使用正向迭代器正向list中的元素
    // list<int>::iterator it = l.begin(); // C++98中语法
    auto it = l.begin();                   // C++11之后推荐写法
    while (it != l.end())
    {
        cout << *it << " ";
        ++it;
    }
    cout << endl;

    // 使用反向迭代器逆向打印list中的元素
    // list<int>::reverse_iterator rit = l.rbegin();
    auto rit = l.rbegin();
    while (rit != l.rend())
    {
        cout << *rit << " ";
        ++rit;
    }
    cout << endl;
}

(3)list capacity


(4)list element access


(5)list modifiers

// list插入和删除
// push_back/pop_back/push_front/pop_front
void TestList3()
{
    int array[] = {1, 2, 3};
    list<int> L(array, array + sizeof(array) / sizeof(array[0]));
    
    L.push_back(4); // 在list的尾部插入4
    L.push_front(0); // 在list的头部插入0
    PrintList(L);
    
    L.pop_back(); // 删除list尾部节点
    L.pop_front(); // 删除list头部节点
    PrintList(L);
}
// insert /erase 
void TestList4()
{
    int array1[] = {1, 2, 3};
    list<int> L(array1, array1 + sizeof(array1) / sizeof(array1[0]));
   
    auto pos = ++L.begin(); // 获取链表中第二个节点
    cout << *pos << endl;
  
    L.insert(pos, 4); // 在pos前插入值为4的元素
    PrintList(L);
   
    L.insert(pos, 5, 5); // 在pos前插入5个值为5的元素
    PrintList(L);
   
    vector<int> v{7, 8, 9};
    L.insert(pos, v.begin(), v.end()); // 在pos前插入[v.begin(), v.end)区间中的元素
    PrintList(L);
   
    L.erase(pos); // 删除pos位置上的元素
    PrintList(L);
   
    L.erase(L.begin(), L.end()); // 删除list中[begin, end)区间中的元素,即删除list中的所有元素
    PrintList(L);
}
// resize/swap/clear
void TestList5()
{
    // 用数组来构造list
    int array1[] = {1, 2, 3};
    list<int> l1(array1, array1 + sizeof(array1) / sizeof(array1[0]));
    PrintList(l1);
   
    list<int> l2;
    l1.swap(l2); // 交换l1和l2中的元素
    PrintList(l1);
    PrintList(l2);
  
    l2.clear(); // 将l2中的元素清空
    cout << l2.size() << endl;
}

(6)list的迭代器失效 
void TestListIterator1()
{
    int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
    list<int> l(array, array+sizeof(array)/sizeof(array[0]));
    auto it = l.begin();
    while (it != l.end())
    {
        // erase()函数执行后,it所指向的节点已被删除,因此it无效,在下一次使用it时,必须先给其赋值
        l.erase(it); 
        ++it;
    }
}

// 改正
void TestListIterator()
{
    int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
    list<int> l(array, array+sizeof(array)/sizeof(array[0]));
    auto it = l.begin();
    while (it != l.end())
    {
        l.erase(it++); // it = l.erase(it);
    }
}


⚪【补充】

二、list的模拟实现

1、模拟实现list

#pragma once

#include <iostream>
using namespace std;
#include <assert.h>

namespace xyl
{
	// List的节点类
	template<class T>
	struct ListNode
	{
		ListNode(const T& val = T())
			: _prev(nullptr)
			, _next(nullptr)
			, _val(val)
		{}

		ListNode<T>* _prev;
		ListNode<T>* _next;
		T _val;
	};

	template<class T, class Ref, class Ptr>
	class ListIterator
	{
		typedef ListNode<T> Node;
		typedef ListIterator<T, Ref, Ptr> Self;

		// Ref 和 Ptr 类型需要重定义下,实现反向迭代器的时候需要用到
	public:
		typedef Ref Ref;
		typedef Ptr Ptr;
	public:
		// 构造
		ListIterator(Node* node = nullptr)
			: _node(node)
		{}

		// 具有指针类似行为
		Ref operator*()
		{
			return _node->_val;
		}

		Ptr operator->()
		{
			return &(operator*());
		}

		// 迭代器支持移动
		Self& operator++()
		{
			_node = _node->_next;
			return *this;
		}

		Self operator++(int)
		{
			Self temp(*this);
			_node = _node->_next;
			return temp;
		}

		Self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}

		Self operator--(int)
		{
			Self temp(*this);
			_node = _node->_prev;
			return temp;
		}

		// 迭代器支持比较
		bool operator!=(const Self& l)const
		{
			return _node != l._node;
		}

		bool operator==(const Self& l)const
		{
			return _node != l._node;
		}

		Node* _node;
	};

	template<class Iterator>
	class ReverseListIterator
	{
		// 注意:这里typename的作用是明确告诉编译器,Ref是Iterator类中的一个类型,而不是静态成员变量
		// 否则编译器编译时就不知道Ref是Iterator中的类型还是静态成员变量
		// 因为静态成员变量也是按照 类名::静态成员变量名 的方式访问的
	public:
		typedef typename Iterator::Ref Ref;
		typedef typename Iterator::Ptr Ptr;
		typedef ReverseListIterator<Iterator> Self;
	public:
		// 构造
		ReverseListIterator(Iterator it)
			: _it(it)
		{}

		// 具有指针类似行为
		Ref operator*()
		{
			Iterator temp(_it);
			--temp;
			return *temp;
		}

		Ptr operator->()
		{
			return &(operator*());
		}

		// 迭代器支持移动
		Self& operator++()
		{
			--_it;
			return *this;
		}

		Self operator++(int)
		{
			Self temp(*this);
			--_it;
			return temp;
		}

		Self& operator--()
		{
			++_it;
			return *this;
		}

		Self operator--(int)
		{
			Self temp(*this);
			++_it;
			return temp;
		}

		// 迭代器支持比较
		bool operator!=(const Self& l)const
		{
			return _it != l._it;
		}

		bool operator==(const Self& l)const
		{
			return _it != l._it;
		}

		Iterator _it;
	};

	template<class T>
	class list
	{
		typedef ListNode<T> Node;

	public:
		// 正向迭代器
		typedef ListIterator<T, T&, T*> iterator;
		typedef ListIterator<T, const T&, const T&> const_iterator;

		// 反向迭代器
		typedef ReverseListIterator<iterator> reverse_iterator;
		typedef ReverseListIterator<const_iterator> const_reverse_iterator;
	public:
		// List的构造
		list()
		{
			CreateHead();
		}

		list(int n, const T& value = T())
		{
			CreateHead();
			for (int i = 0; i < n; ++i)
				push_back(value);
		}

		template <class Iterator>
		list(Iterator first, Iterator last)
		{
			CreateHead();
			while (first != last)
			{
				push_back(*first);
				++first;
			}
		}

		list(const list<T>& l)
		{
			CreateHead();

			// 用l中的元素构造临时的temp,然后与当前对象交换
			list<T> temp(l.begin(), l.end());
			this->swap(temp);
		}

		list<T>& operator=(list<T> l)
		{
			this->swap(l);
			return *this;
		}

		~list()
		{
			clear();
			delete _head;
			_head = nullptr;
		}

		// List的迭代器
		iterator begin()
		{
			return iterator(_head->_next);
		}

		iterator end()
		{
			return iterator(_head);
		}

		const_iterator begin()const
		{
			return const_iterator(_head->_next);
		}

		const_iterator end()const
		{
			return const_iterator(_head);
		}

		reverse_iterator rbegin()
		{
			return reverse_iterator(end());
		}

		reverse_iterator rend()
		{
			return reverse_iterator(begin());
		}

		const_reverse_iterator rbegin()const
		{
			return const_reverse_iterator(end());
		}

		const_reverse_iterator rend()const
		{
			return const_reverse_iterator(begin());
		}

		// List的容量相关
		size_t size()const
		{
			Node* cur = _head->_next;
			size_t count = 0;
			while (cur != _head)
			{
				count++;
				cur = cur->_next;
			}

			return count;
		}

		bool empty()const
		{
			return _head->_next == _head;
		}

		void resize(size_t newsize, const T& data = T())
		{
			size_t oldsize = size();
			if (newsize <= oldsize)
			{
				// 有效元素个数减少到newsize
				while (newsize < oldsize)
				{
					pop_back();
					oldsize--;
				}
			}
			else
			{
				while (oldsize < newsize)
				{
					push_back(data);
					oldsize++;
				}
			}
		}

		// List的元素访问操作
		// 注意:List不支持operator[]
		T& front()
		{
			return _head->_next->_val;
		}

		const T& front()const
		{
			return _head->_next->_val;
		}

		T& back()
		{
			return _head->_prev->_val;
		}

		const T& back()const
		{
			return _head->_prev->_val;
		}

		// List的插入
		void push_back(const T& val)
		{
			insert(end(), val);
		}

		// List的删除
		void pop_back()
		{
			erase(--end());
		}

		void push_front(const T& val)
		{
			insert(begin(), val);
		}

		void pop_front()
		{
			erase(begin());
		}

		// 在pos位置前插入值为val的节点
		iterator insert(iterator pos, const T& val)
		{
			Node* pNewNode = new Node(val);
			Node* pCur = pos._node;
			// 先将新节点插入
			pNewNode->_prev = pCur->_prev;
			pNewNode->_next = pCur;
			pNewNode->_prev->_next = pNewNode;
			pCur->_prev = pNewNode;
			return iterator(pNewNode);
		}

		// 删除pos位置的节点,返回该节点的下一个位置
		iterator erase(iterator pos)
		{
			// 找到待删除的节点
			Node* pDel = pos._node;
			Node* pRet = pDel->_next;

			// 将该节点从链表中拆下来并删除
			pDel->_prev->_next = pDel->_next;
			pDel->_next->_prev = pDel->_prev;
			delete pDel;

			return iterator(pRet);
		}

		void clear()
		{
			Node* cur = _head->_next;

			// 采用头删除删除
			while (cur != _head)
			{
				_head->_next = cur->_next;
				delete cur;
				cur = _head->_next;
			}

			_head->_next = _head->_prev = _head;
		}

		void swap(bite::list<T>& l)
		{
			std::swap(_head, l._head);
		}

	private:
		void CreateHead()
		{
			_head = new Node;
			_head->_prev = _head;
			_head->_next = _head;
		}
	private:
		Node* _head;
	};
}


// 对模拟实现的list进行测试
// 正向打印链表
template<class T>
void PrintList(const xyl::list<T>& l)
{
	auto it = l.begin();
	while (it != l.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

// 测试List的构造
void TestBiteList1()
{
	xyl::list<int> l1;
	xyl::list<int> l2(10, 5);
	PrintList(l2);

	int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
	xyl::list<int> l3(array, array + sizeof(array) / sizeof(array[0]));
	PrintList(l3);

	xyl::list<int> l4(l3);
	PrintList(l4);

	l1 = l4;
	PrintList(l1);
}

// PushBack()/PopBack()/PushFront()/PopFront()
void TestBiteList2()
{
	// 测试PushBack
	xyl::list<int> l;
	l.push_back(1);
	l.push_back(2);
	l.push_back(3);
	PrintList(l);

	// 测试PopBack
	l.pop_back();
	l.pop_back();
	PrintList(l);

	l.pop_back();
	cout << l.size() << endl;

	// 测试PushFront
	l.push_front(1);
	l.push_front(2);
	l.push_front(3);
	PrintList(l);

	// 测试PopFront
	l.pop_front();
	l.pop_front();
	PrintList(l);

	l.pop_front();
	cout << l.size() << endl;
}

// 测试insert和erase
void TestBiteList3()
{
	int array[] = {1, 2, 3, 4, 5};
	xyl::list<int> l(array, array + sizeof(array) / sizeof(array[0]));

	auto pos = l.begin();
	l.insert(l.begin(), 0);
	PrintList(l);

	++pos;
	l.insert(pos, 2);
	PrintList(l);

	l.erase(l.begin());
	l.erase(pos);
	PrintList(l);

	// pos指向的节点已经被删除,pos迭代器失效
	cout << *pos << endl;

	auto it = l.begin();
	while (it != l.end())
	{
		it = l.erase(it);
	}
	cout << l.size() << endl;
}

// 测试反向迭代器
void TestBiteList4()
{
	int array[] = {1, 2, 3, 4, 5};
	xyl::list<int> l(array, array + sizeof(array) / sizeof(array[0]));

	auto rit = l.rbegin();
	while (rit != l.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;

	const xyl::list<int> cl(l);
	auto crit = l.rbegin();
	while (crit != l.rend())
	{
		cout << *crit << " ";
		++crit;
	}
	cout << endl;
}

2、list的反向迭代器 

template<class Iterator>
class ReverseListIterator
{
    // 注意:这里typename的作用是明确告诉编译器,Ref是Iterator类中的一个类型,而不是静态成员变量
    // 否则编译器编译时就不知道Ref是Iterator中的类型还是静态成员变量
    // 因为静态成员变量也是按照 类名::静态成员变量名 的方式访问的
public:
	typedef typename Iterator::Ref Ref;
    typedef typename Iterator::Ptr Ptr;
	typedef ReverseListIterator<Iterator> Self;
public:
	// 构造
	ReverseListIterator(Iterator it)
		: _it(it)
	{}

	// 具有指针类似行为
	Ref operator*()
	{
		Iterator temp(_it);
		--temp;
		return *temp;
	}

	Ptr operator->()
	{
		return &(operator*());
	}

	// 迭代器支持移动
	Self& operator++()
	{
		--_it;
		return *this;
	}

	Self operator++(int)
	{
		Self temp(*this);
		--_it;
		return temp;
	}

	Self& operator--()
	{
		++_it;
		return *this;
	}

	Self operator--(int)
	{
		Self temp(*this);
		++_it;
		return temp;
	}

	// 迭代器支持比较
	bool operator!=(const Self& l)const
	{
		return _it != l._it;
	}

	bool operator==(const Self& l)const
	{
		return _it != l._it;
	}

	Iterator _it;
};

三、listvector的对比

举报

相关推荐

0 条评论