0
点赞
收藏
分享

微信扫一扫

MonoHuman: Animatable Human Neural Field from Monocular Video 翻译

梦幻之云 2024-09-08 阅读 21

1.list概述

list 和 vector 是两个最常被使用的容器,什么时机下最适合使用哪一种容器,必须视元素的多寡、元素的构造复杂度、 元素存取行为的特征而定。

下图是 list 示意图 : 环状链表的尾端加上一个空白节点,符合“前闭后开”区间。

2.list的使用

(1) 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迭代器的使用
// 注意:遍历链表只能用迭代器和范围for
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(修改器)

#include <list>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
	list<int> ilist; 
	cout << "size=" << ilist.size() << endl;// size=0
	ilist.push_back(0); 
	ilist.push_back(1); 
	ilist.push_back(2); 
	ilist.push_back(3); 
	ilist.push_back(4); 
	cout << "size=" << ilist.size() << endl;//size=5

	list<int>::iterator ite; 
	for (ite = ilist.begin(); ite != ilist.end(); ++ite)
	{
		cout << *ite << ' ';//0 1 2 3 4
	}
	cout << endl;


	ite = find(ilist.begin(), ilist.end(), 3);
	if (ite != ilist.end())
	{
		ilist.insert(ite, 99);
	}
	cout << "size=" << ilist.size() << endl;// size=6
	cout << *ite << endl;// 3
	
	for (ite = ilist.begin(); ite != ilist.end(); ++ite)//0 1 2 99 3 4
		cout << *ite << ' ';
	cout << endl;
	ite = find(ilist.begin(), ilist.end(), 1); 
	if (ite != ilist.end())
		cout << *(ilist.erase(ite)) << endl;//2

	for (ite = ilist.begin(); ite != ilist.end(); ++ite)//0 2 99 3 4
		cout << *ite << ' ';
	cout << 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);
	}
}

3.list的模拟实现

(1) list的节点(ListNode)

list 本身和 list 的节点是不同的结构,需要分开设计,以下是根据 STL 设计的 list 的节点(ListNode)结构:

template <class T>
struct ListNode // struct默认成员是公有的
{
	ListNode(const T& val = T())
		:_prev(nullptr)
		,_next(nullptr)
		,_data(val)
	{}

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

(2) list的迭代器(ListIterator)

list 不能再像 vector 一样以普通指针作为迭代器,因为其节点不保证在存储空间里连续存在。list迭代器必须有能力指向list节点,并有能力进行正确的递增、递减、取值、成员存取等操作。所谓“list 正确的递增、递减、取值、成员存取”操作是指,递增时指向下一个节点,递减时指向下一个节点,取值时取的是节点的数据值,成员取用时取的是节点的成员

//List的迭代器类模版,实例化了两个类
template<class T, class Ref, class Ptr>
class ListIterator
{
    typedef ListNode<T>* PNode;
    typedef ListIterator<T, Ref, Ptr> Self;

public:
    ListIterator(PNode pNode = nullptr)
        :_pNode(pNode)
    {}

    ListIterator(const Self& l)
        :_pNode(l._pNode)
    {}

    T& operator*()
    {//取得是节点的数值
        return (*_pNode)._data;
    }
    T* operator->()
    {
        return &(operator*());
    }

    Self& operator++()
    {
        _pNode = (*_pNode)._next;
        return *this;
    }
    Self operator++(int)//前置++
    {
        Self tmp = *this;
        _pNode = (*_pNode)._next;
        return tmp;//返回++之前的
    }
    Self& operator--()
    {
        _pNode = (*_pNode)._prev;
        return *this;
    }
    Self operator--(int)
    {
        Self tmp = *this;
        _pNode = _pNode._prev;
        return tmp;//返回++之前的
    }
    bool operator!=(const Self& l)
    {
        return !(_pNode == l._pNode);
    }
    bool operator==(const Self& l)
    {
        return _pNode == l._pNode;
    }

    PNode _pNode;//迭代器的内部要有一个普通指针,指向list的节点
};

(3) list的数据结构

//list类
template<class T>
class list // class 默认是私有的
{
    typedef ListNode<T> Node;
public:
    typedef Node* PNode;
    
    //实现...

private:
    PNode _pHead;//只需要一个指针,完成整个双向环状链表
    size_t _size;//STL中没有,自己实现为了方便加的

};

(4) list的构造与内存管理 

    // List的构造
    list()
    {
        CreateHead();//产生一个空链表(一个指向自己的空节点)
    }
    list(int n, const T& value = T())
    {
        CreateHead();
        while (n--)
        {
            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();
        list<T> tmp(l.begin(), l.end());
        swap(tmp);
    }
    list<T>& operator=(list<T> l)
    {
        swap(l);
        return *this;
    }
    ~list()
    {
        clear();
        delete[] _pHead;
        _pHead = nullptr;
    }

private:
    void CreateHead()
    {
        _pHead = new Node[1];//配置一个节点空间,头尾指向自己
        _pHead->_next = _pHead;
        _pHead->_prev = _pHead;
    }
void push_back(const T& val){ insert(end(), val);}
// 在pos位置前插入值为val的节点
iterator insert(iterator pos, const T& val)
{
    PNode tmp = new Node[1];
    tmp->_data = val;
    PNode pcur = pos._pNode->_prev;
    pcur->_next = tmp;
    tmp->_prev = pcur;
    pos._pNode->_prev = tmp;
    tmp->_next = pos._pNode;
    ++_size;
    return tmp;
}

插入完成之后,新节点将位于插入点所指向之节点的前方—这是STL对于“插入操作”的标准规范。

(5) list的元素操作

// List Modify
void push_back(const T& val)
{
    insert(end(), val);
}
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)
{
    PNode tmp = new Node[1];
    tmp->_data = val;
    PNode pcur = pos._pNode->_prev;
    pcur->_next = tmp;
    tmp->_prev = pcur;
    pos._pNode->_prev = tmp;
    tmp->_next = pos._pNode;
    ++_size;
    return tmp;
}
// 删除pos位置的节点,返回该节点的下一个位置
iterator erase(iterator pos)
{
    PNode pcur = pos._pNode->_prev;
    PNode pnext = pos._pNode->_next;
    pcur->_next = pnext;
    pnext->_prev = pcur;
    delete[] pos._pNode;
    --_size;
    return pnext;
}
//清除整个链表
void clear()
{
    auto cur = begin();
    while (cur != end())
    {
        cur = erase(cur);
    }
}

(6) 模拟实现.h

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

namespace zyt
{
    //List的节点类
    template <class T>
    struct ListNode // struct默认成员是公有的
    {
        ListNode(const T& val = T())
            :_prev(nullptr)
            , _next(nullptr)
            , _data(val)
        {}

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

    //List的迭代器类模版,实例化了两个类
    template<class T, class Ref, class Ptr>
    class ListIterator
    {
        typedef ListNode<T>* PNode;
        typedef ListIterator<T, Ref, Ptr> Self;

    public:
        ListIterator(PNode pNode = nullptr)
            :_pNode(pNode)
        {}

        ListIterator(const Self& l)
            :_pNode(l._pNode)
        {}

        T& operator*()
        {
            return (*_pNode)._data;
        }
        T* operator->()
        {
            return &(operator*());
        }

        Self& operator++()
        {
            _pNode = (*_pNode)._next;
            return *this;
        }
        Self operator++(int)//前置++
        {
            Self tmp = *this;
            _pNode = (*_pNode)._next;
            return tmp;//返回++之前的
        }
        Self& operator--()
        {
            _pNode = (*_pNode)._prev;
            return *this;
        }
        Self operator--(int)
        {
            Self tmp = *this;
            _pNode = _pNode._prev;
            return tmp;//返回++之前的
        }
        bool operator!=(const Self& l)
        {
            return !(_pNode == l._pNode);
        }
        bool operator==(const Self& l)
        {
            return _pNode == l._pNode;
        }

        PNode _pNode;
    };


    //list类
    template<class T>
    class list // class 默认是私有的
    {
        typedef ListNode<T> Node;
        typedef Node* PNode;
    public:
        typedef ListIterator<T, T&, T*> iterator;
        typedef ListIterator<T, const T&, const T&> const_iterator;
    public:
        ///
        // List的构造
        list()
        {
            CreateHead();//产生一个空链表(一个指向自己的空节点)
        }
        list(int n, const T& value = T())
        {
            CreateHead();
            while (n--)
            {
                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();
            list<T> tmp(l.begin(), l.end());
            swap(tmp);
        }
        list<T>& operator=(list<T> l)
        {
            swap(l);
            return *this;
        }
        ~list()
        {
            clear();
            delete[] _pHead;
            _pHead = nullptr;
        }


        ///
        // List Iterator
        iterator begin()
        {
            return ((*_pHead)._next);
        }
        iterator end()
        {
            return _pHead;
        }
        const_iterator begin() const
        {
            return ((*_pHead)._next);
        }
        const_iterator end() const
        {
            return _pHead;

        }

        ///
        // List Capacity
        size_t size()const
        {
            return _size;
        }
        bool empty()const
        {
            return _pHead->_next == _pHead;
        }

        
        // List Access
        T& front()
        {
            return *begin();
        }
        const T& front()const
        {
            return *begin();
        }
        T& back()
        {
            return *end();
        }
        const T& back()const
        {
            return *end();
        }

        
        // List Modify
        void push_back(const T& val)
        {
            insert(end(), val);
        }
        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)
        {
            PNode tmp = new Node[1];
            tmp->_data = val;
            PNode pcur = pos._pNode->_prev;
            pcur->_next = tmp;
            tmp->_prev = pcur;
            pos._pNode->_prev = tmp;
            tmp->_next = pos._pNode;
            ++_size;
            return tmp;
        }
        // 删除pos位置的节点,返回该节点的下一个位置
        iterator erase(iterator pos)
        {
            PNode pcur = pos._pNode->_prev;
            PNode pnext = pos._pNode->_next;
            pcur->_next = pnext;
            pnext->_prev = pcur;
            delete[] pos._pNode;
            --_size;
            return pnext;
        }
        //清除整个链表
        void clear()
        {
            auto cur = begin();
            while (cur != end())
            {
                cur = erase(cur);
            }
        }
        void swap(list<T>& l)
        {
            std::swap(_pHead, l._pHead);
            std::swap(_size, l._size);
        }
    private:
        void CreateHead()
        {
            _pHead = new Node[1];//配置一个节点空间,头尾指向自己
            _pHead->_next = _pHead;
            _pHead->_prev = _pHead;
        }
    private:
        PNode _pHead;
        size_t _size;

    };
}

(7) 测试.cpp

// 打印各类容器(类)
template<class T>
void PrintList(const zyt::list<T>& l)
{
    auto it = l.begin();
    while (it != l.end())
    {
        cout << *it << " ";
        ++it;
    }

    cout << endl;
}

void TestList3()
{
    int array[] = { 1, 2, 3, 4, 5 };
    //zyt::list<int> l(array, array + sizeof(array) / sizeof(array[0]));
    zyt::list<int> l;
    l.push_back(1);
    l.push_back(2);
    l.push_back(3);
    l.push_back(4);
    l.push_back(5);
    PrintList(l);

    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;
}


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

    l.pop_back();
    l.pop_back();
    PrintList(l);

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

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

    l.pop_front();
    l.pop_front();
    PrintList(l);

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

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

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

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

    l1 = l4;
    PrintList(l1);
}
int main()
{
    TestList1();
    return 0;
}

4.list与vector的区别 

举报

相关推荐

0 条评论