p15~p22基本链表容器和高级链表容器迭代器

news2024/10/7 20:24:46

STL

  • 一、自制链表容器/基本链表容器
    • 1.1 首/尾部增删节点
    • 1.2 获取首/尾部的元素
    • 1.3 清空链表7 / 判空链表 / 链表大小8
    • 1.4 缺省构造0/拷贝构造10/析构函数9
    • 1.5 输出流操作符重载
  • 二、迭代器原理
    • 2.1 迭代器概念
    • 2.2 迭代器的分类
  • 三、迭代器实现
    • 3.1 正向非常迭代类
    • 3.2 正向非常迭代器
  • 四、正向常迭代器
    • 4.1 正向常迭代类
    • 4.2 正向常迭代器
  • 五、查找/排序功能

一、自制链表容器/基本链表容器

自制链表容器

自制一个每个节点可存储数据类型不固定的链表容器。

功能列表:

  • 首/尾部增删节点
  • 获取首/尾部的元素
  • 清空链表 / 判空链表 / 链表大小
  • 缺省构造/拷贝构造/析构函数
  • 输出流操作符重载

双向链表:每个节点至少包含三个部分,前指针、中间数据、后指针。

在这里插入图片描述

在这里插入图片描述

双向链表头结点的头指针指向为空(非循环链表中指向尾节点);尾结点同样指向尾空。

在这里插入图片描述
只需要两个变量即可表示一个list对象,

在这里插入图片描述

1.1 首/尾部增删节点

  • 链表为空1
bool empty(){
         return m_head==NULL && m_tail==NULL;
}
  • 添加链表头节点2

在这里插入图片描述

准备工作:红色部分代码: new Node(NULL, data, m_head);

在这里插入图片描述

第一步:原来的m_head指向新节点

m_head = new Node(NULL, data, m_head);

第二步:原来的第一个节点的头指针m_prev应指向新节点

m_head->next->m_prev = m_head;

void push_front(T const& data){
     m_head = new node(NULL,data,m_head);
     if(m_head->m_next)
         m_head->m_next->m_prev = m_head;
     else
         m_tail = m_head;
}
  • 删除链表头节点3
    在这里插入图片描述

在这里插入图片描述

如上直接delete m_head不可取,这样会导致无法找到list;

在这里插入图片描述

所以在删除之前应该先将第二个节点备份,再使之成为新的头结点:node* pnode = m_head; delete m_head;

在这里插入图片描述
再将m_head指向备份节点并将其备份节点的头指针指向NULL

void pop_front(){
     if(empty())
         return;
     node* pnode = m_head->m_next;
     delete(m_head);
     if(pnode)
         pnode->m_prev = NULL;
     else
         m_tail = NULL;
     m_head = pnode;
 }
  • 添加链表尾节点5
void push_back(T const& data){
       m_tail = new node(m_tail, data, NULL);
       if(m_tail->m_prev)
           m_tail->m_prev->m_next = m_tail;
       else
           m_head = m_tail;
   }
  • 删除链表尾节点6
void pop_back(){
     if(empty())
         return;
     node* pnode = m_tail->m_prev;
     delete(m_tail);
     if(pnode)
         pnode->m_next = NULL;
     else
         m_head = NULL;
     m_tail = pnode;
 }

1.2 获取首/尾部的元素

  • 获取头节点数据4
 T& front(){
     if(empty())
         throw underflow_error("front():null node");
     return m_head->m_data;
 }
 T const& front()const{
     return const_cast<list*>(this)->front();
 }
  • 获取尾节点数据
T& back(){
     if(empty())
         throw underflow_error("back():null node");
     return m_tail->m_data;
 }
 T const& back()const{
     return const_cast<list*>(this)->back();
 }

1.3 清空链表7 / 判空链表 / 链表大小8

void clear(){
         while(!empty())
             pop_front();
     }
size_t size(){
         size_t i = 0;
         for(node* pnode=m_head; pnode; pnode=pnode->m_next)
             i++;
         return i;
     }

1.4 缺省构造0/拷贝构造10/析构函数9

编译器默认提供的拷贝构造属于浅拷贝,此处应该实现深拷贝。

    list():m_head(NULL),m_tail(NULL){}

    //深拷贝
    list(list const& that):m_head(NULL),m_tail(NULL){
         for(node* pnode=that.m_head; pnode; pnode=pnode->m_next)
             push_back(pnode->m_data);
    }

    ~list(){
         clear();
    }
size_t size(){
         size_t i = 0;
         for(node* pnode=m_head; pnode; pnode=pnode->m_next)
             i++;
         return i;
}

1.5 输出流操作符重载

ostream& operator<<(ostream& os, list const& l){
         for(node* pnode=l.m_head; pnode; pnode=pnode->m_next)
             os << pnode->m_data << ' ';
         return os;
}

baseList.cpp

#include <iostream>
#include <stdexcept>  //提供关于异常类的声明
using namespace std;
template<class T>class list{
public:
//
//缺省构造
//
     list():m_head(NULL),m_tail(NULL){}
//
//拷贝构造(可以后边实现)
//
     list(list const& that):m_head(NULL),m_tail(NULL){
		for(node*pnode=that.m_head; pnode; pnode=pnode->m_next){
			push_back(pnode->m_data);
		}
	}
//
//析构函数
//
     ~list(){
         clear();
     }
//
//链表判空
//
   bool empty(){
       retur m_head == NULL && m_tail =+ NULL;
   }
//
//添加头结点
//
   void push_front(T const & data){
       if(empty())
			return;
		node* pnode = m_head->m_next;
		delete m_head;
		if(pnode)
			pnode->m_prev = NULL;
		else
			m_tail = NULL;
		m_head = pnode;
   }
//
//删除链表头结点
//
    void pop_front(){
    node* pnode = m_head;
    delete m_head;
    
    }
//
//获取头结点元素
//
    T& front(){
        if(empty())
			throw underflow_error("null node");
		return m_head->m_data;
    }
    //此处针对有const修饰的list
    T const& front()const{
        return const_cast<list*>(this)->front();
    }
//
//添加尾结点
//
    void push_back(T const& data){
		m_tail = new node(m_tail,data,NULL);
		if(m_tail->m_prev)
			m_tail->m_prev->m_next = m_tail;
		else
			m_head = m_tail;
	}
//
//删除尾结点
//
    void pop_back(){
		if(empty())
			return;
		node* pnode = m_tail->m_prev;
		delete m_tail;
		if(pnode)
			pnode->m_next = NULL;
		else
			m_head = NULL;
		m_tail = pnode;
	}
//
//获取尾结点数据
//
    T& back(){
		if(empty())
			throw underflow_error("null node");
		return m_tail->m_data;
	}
	T const& back()const{
		return const_cast<list*>(this)->back();
	}
//
//清空链表
//
    void clear(){
		while(!empty()){
			pop_front();
		}	
	}
//
//获取链表大小
//
    size_t size(){
		size_t i=0;
		for(node* pnode=m_head; pnode; pnode=pnode->m_next)
			++i;
		return i;
	}
private:
//
//节点类
//
	class node{
	public:
		node(node*prev,T const& data,node*next):m_prev(prev),m_data(data),m_next(next){}
		//三个成员
		node* m_prev;//前指针
		T m_data;//节点数据
		node* m_next;//后指针
	};
	//list只需要两个成员变量就可以表示
	node* m_head;//链表头
	node* m_tail;//链表尾
	//声明为友元即可访问私有成员
	friend ostream& operator<<(ostream& os, list<int>& l);
};
//以上代码模拟容器
//------------------------
//以下代码模拟普通用户
ostream& operator<<(ostream& os, list<int>& l){
	for(list<int>::node* pnode=l.m_head; pnode; pnode=pnode->m_next){
		os << pnode->m_data << ' ';
	}
	return os;
}
int main(){
	list<int> ls;
	for(int i=0; i<5; i++)
		ls.push_front(10+i);
	for(int i=0; i<5; i++)
		ls.push_back(100+i);
	cout << ls << endl;
	ls.pop_front();
	ls.pop_back();
	cout << ls << endl;
	return 0;
}

二、迭代器原理

2.1 迭代器概念

  • 迭代器就是一个类(迭代类)对象。

    上文所说的每一个节点即为一个迭代器对象;

    迭代器三个成员皆为指针:开始指向、当前指向、终止指向分别;开始指向指向链表头结点,终止指向指向链表尾结点,当前指向可以指向开始指向和终止指向圈定范围的所有节点(包括首尾节点)

在这里插入图片描述

在这里插入图片描述

  • 通过对这个对象进行操作(例如 ++/–)可以对链表容器进行某种程度(全局或局部)的遍历(又名遍历器)。

  • 这样可以使用户不必关心链表容器的内部结构

    上文自制链表操作时需要对链表内部结构非常清楚,而迭代器不需要。
    在这里插入图片描述
    在这里插入图片描述

访问:++/–;取值:*;判断相等否:==/!=
在这里插入图片描述

红色为起始迭代器,蓝色为终止迭代器,区别在于蓝色的中间指向是指向链表尾结点的下一个位置(实际为NULL)。

在这里插入图片描述

在对红色迭代器遍历时,当红色迭代器和蓝色迭代器相等时,遍历终止。

2.2 迭代器的分类

  • 正向非常迭代类 iterator

  • 正向常迭代类 const_iterator

  • 反向非常迭代类 reverse_iterator

  • 反向常迭代类 const_reverse_iterator

三、迭代器实现

3.1 正向非常迭代类

class iterator{
     public:        	
	iterator(node*start,node*cur,node*end):
		m_start(start),m_cur(cur),m_end(end){}
          T& operator*()	{             ...          }
          iterator& operator++()	{              ...          }
          iterator& operator--()	{              ...          }
          bool operator==(iterator const& that)const	{              ...          }
          bool operator!=(iterator const& that)const	{              ...          }
      private:
          node* m_start;
          node* m_cur;
          node* m_end;
};

3.2 正向非常迭代器

  • 起始迭代器
iterator begin(){
         return iterator(m_head,m_head,m_tail);
 }
  • 终止迭代器
iterator end(){
        return iterator(m_head,NULL,m_tail);
}
  • 迭代器指向位置添加节点

在这里插入图片描述

void insert(iterator const& loc, T const& data){
         if(loc==end()){
             push_back(data);
         }else{
             node* pnode = new node(loc.m_cur->m_prev, data, loc.m_cur);
             if(pnode->m_prev)
                 pnode->m_prev->m_next = pnode;
             else
                 m_head = pnode;
             pnode->m_next->m_prev = pnode;
        }
     }
  • 删除迭代器指向的节点
    在这里插入图片描述

void erase(iterator const& loc){
         if(loc==end())
             throw underflow_error("null node");
         node* pdel = loc.m_cur;
         node* pnext = loc.m_cur->m_next;
         if(pdel->m_prev)
             pdel->m_prev->m_next = pdel->m_next;
         else
             m_head = pdel->m_next;
         if(pdel->m_next)
             pdel->m_next->m_prev = pdel->m_prev;
         else
             m_tail = pdel->m_prev;
         delete pdel;
}

四、正向常迭代器

4.1 正向常迭代类

class const_iterator{
     public:       
         const_iterator(iterator const& it):m_it(it){}
          T const& operator*()	{             ...          }
          const_iterator& operator++()	{              ...          }
          const_iterator& operator--()	{              ...          }
          bool operator==(const_iterator const& that)const	{              ...          }
          bool operator!=(const_iterator const& that)const	{              ...          }
      private:
          iterator m_it;
};

4.2 正向常迭代器

在这里插入图片描述

  • 起始迭代器
const_iterator begin()const{
         return iterator(m_head,m_head,m_tail);
 }
  • 终止迭代器
const_iterator end()const{
         return iterator(m_head,NULL,m_tail);
 }

五、查找/排序功能

  • 查找功能
template<class IT,class T>IT find(IT const& begin, IT const& end, T const& data){
     for(IT it=begin; it!=end; ++it){
         if(*it==data)
             return it;
     }
     return end;
 }
  • 利用“<”实现排序
template<class IT>IT sort(IT const& begin, IT const& end){
     IT p = begin;     IT last = end;     --last;
     for(IT i=begin, j=last; i!=j; ){
         while(i!=p && *i<*p)
             ++i;
         if(i!=p){
             swap(*i,*p);             p = i;
         }
         while(j!=p && *p<*j)
             --j;
         if(j!=p){
             swap(*p,*j);             p = j;
         }
     }
     //递归代码;
     IT it = begin;
     ++it;
     if(p!=begin && p!=it)
         sort(begin,p);
     it = p;
     ++it;
     if(it!=end && it!=last)
         sort(it,end);

}
  
  • 利用“比较器”实现排序
template<class ITclass CMP>IT sort(IT const& begin, IT const& end, CMP cmp){
     IT p = begin;     IT last = end;     --last;
     for(IT i=begin, j=last; i!=j; ){
         while(i!=p && cmp(*i,*p))
             ++i;
         if(i!=p){
             swap(*i,*p);             p = i;
         }
         while(j!=p && cmp(*p,*j))
             --j;
         if(j!=p){
             swap(*p,*j);             p = j;
         }
     }
     //递归代码;
     IT it = begin;
     ++it;
     if(p!=begin && p!=it)
         sort(begin,p,cmp);
     it = p;
     ++it;
     if(it!=end && it!=last)
         sort(it,end,cmp);
}

list.cpp

#include <iostream>
#include <stdexcept>
using namespace std;
template<class T>class list{
public:
//
//缺省构造
//
	list():m_head(NULL),m_tail(NULL){}
//
//拷贝构造
//
	list(list const& that):m_head(NULL),m_tail(NULL){
		for(node*pnode=that.m_head; pnode; pnode=pnode->m_next){
			push_back(pnode->m_data);
		}
	}
//
//析构函数
//
	~list(){
		clear();
	}
//
//链表判空
//
	bool empty(){
		return m_head==NULL && m_tail==NULL;
	}
//
//添加头节点
//
	void push_front(T const& data){
		m_head = new node(NULL,data,m_head);
		if(m_head->m_next)
			m_head->m_next->m_prev = m_head;
		else
			m_tail = m_head;
	}
//
//删除链表头节点
//
	void pop_front(){
		if(empty())
			return;
		node* pnode = m_head->m_next;
		delete m_head;
		if(pnode)
			pnode->m_prev = NULL;
		else
			m_tail = NULL;
		m_head = pnode;
	}
//
//获取头节点元素
//
	T& front(){
		if(empty())
			throw underflow_error("null node");
		return m_head->m_data;
	}
	T const& front()const{
		return const_cast<list*>(this)->front();
	}
//
//添加尾节点
//
	void push_back(T const& data){
		m_tail = new node(m_tail,data,NULL);
		if(m_tail->m_prev)
			m_tail->m_prev->m_next = m_tail;
		else
			m_head = m_tail;
	}
//
//删除尾节点
//
	void pop_back(){
		if(empty())
			return;
		node* pnode = m_tail->m_prev;
		delete m_tail;
		if(pnode)
			pnode->m_next = NULL;
		else
			m_head = NULL;
		m_tail = pnode;
	}
//
//获取尾节点数据
//
	T& back(){
		if(empty())
			throw underflow_error("null node");
		return m_tail->m_data;
	}
	T const& back()const{
		return const_cast<list*>(this)->back();
	}
//
//清空链表
//
	void clear(){
		while(!empty()){
			pop_front();
		}	
	}
//
//获取链表大小
//
	size_t size(){
		size_t i=0;
		for(node* pnode=m_head; pnode; pnode=pnode->m_next)
			++i;
		return i;
	}
private:
//
//节点类
//
	class node{
	public:
		node(node*prev,T const& data,node*next):m_prev(prev),m_data(data),m_next(next){}
		node* m_prev;//前指针
		T m_data;//节点数据
		node* m_next;//后指针
	};
public:
//
//正向非常迭代类
//
	class iterator{
	public:
		iterator(node*start,node*cur,node*end):m_start(start),
						m_cur(cur),m_end(end){}
		T& operator*(){
			if(m_cur==NULL)
				throw underflow_error("null node");
			return m_cur->m_data;
		}
		iterator& operator++(){
			if(m_cur==NULL)
				m_cur = m_start;
			else
				m_cur = m_cur->m_next;
			return *this;
		}
		iterator& operator--(){
			if(m_cur==NULL)
				m_cur = m_end;
			else
				m_cur = m_cur->m_prev;
			return *this;
		}
		bool operator==(iterator const& that)const{
			return m_start==that.m_start && m_cur==that.m_cur &&
					m_end==that.m_end;
		}
		bool operator!=(iterator const& that)const{
			return !(*this==that);
		}
	private:
		node* m_start;//开始指向
		node* m_cur;//当前指向
		node* m_end;//终止指向
		friend class list;
	};
//
//获取起始迭代器(红色)遍历链表
//
	iterator begin(){
		return iterator(m_head,m_head,m_tail);
	}
//
//获取终止迭代器(蓝色) 结束标志
//
	iterator end(){
		return iterator(m_head,NULL,m_tail);
	}
//
//迭代器指向的位置添加节点
//
	void insert(iterator const& loc, T const& data){
		if(loc==end()){
			push_back(data);
		}else{
			node* pnode = new node(loc.m_cur->m_prev,data,loc.m_cur);
			if(pnode->m_prev)
				pnode->m_prev->m_next = pnode;
			else
				m_head = pnode;
			pnode->m_next->m_prev = pnode;
		}
	}
//
//删除迭代器指向的节点
//
	void erase(iterator const& loc){
		if(loc==end())
			return;
		node* pdel = loc.m_cur;
		if(pdel->m_prev)
			pdel->m_prev->m_next = pdel->m_next;
		else
			m_head = pdel->m_next;
		if(pdel->m_next)	
			pdel->m_next->m_prev = pdel->m_prev;
		else
			m_tail=pdel->m_prev;
		delete pdel;
	}
//
//正向常迭代类
//
	class const_iterator{
	public:
		const_iterator(iterator const& it):m_it(it){}
		T const& operator*(){
			return *m_it;
		}
		const_iterator& operator++(){
			++m_it;
			return *this;
		}
		const_iterator& operator--(){
			--m_it;
			return *this;
		}
		bool operator==(const_iterator const& that)const{
			return m_it==that.m_it;
		}
		bool operator!=(const_iterator const& that)const{
			return !(*this==that);
		}
	private:
		iterator m_it;
	};
//
//获取起始常迭代器
//	
	const_iterator begin()const{
		return iterator(m_head,m_head,m_tail);
	}
//
//获取终止常迭代器
//
	const_iterator end()const{
		return iterator(m_head,NULL,m_tail);
	}
	node* m_head;//链表头
	node* m_tail;//链表尾从
};
//
//比较查找(利用“==”)
//
template<class IT,class T>IT find(IT const& a,IT const& b,T const&data)
{
	for(IT it=a; it!=b; ++it){
		if(*it==data){
			return it;
		}
	}
	return b;
}
//
//快速排序(“<”)
//
template<class IT>void sort(IT const& begin, IT const& end){
	IT p = begin;
	IT last = end;
	--last;
	for(IT i=begin, j=last; i!=j; ){
		while(i!=p && *i<*p)
			++i;
		if(i!=p){
			swap(*i,*p);
			p = i;
		}
		while(j!=p && *p<*j)
			--j;
		if(j!=p){
			swap(*p,*j);
			p = j;
		}
	}
	IT it=begin;
	++it;
	if(p!=begin && p!=it)
		sort(begin,p);
	it=p;
	++it;
	if(it!=end && it!=last)
		sort(it,end);
}
//
//快速排序(“比较器”)
//
template<class IT,class CMP>
void sort(IT const& begin, IT const& end,CMP cmp){
	IT p = begin;
	IT last = end;
	--last;
	for(IT i=begin, j=last; i!=j; ){
		while(i!=p && cmp(*i,*p))//*i<*p)
			++i;
		if(i!=p){
			swap(*i,*p);
			p = i;
		}
		while(j!=p && cmp(*p,*j))//*p<*j)
			--j;
		if(j!=p){
			swap(*p,*j);
			p = j;
		}
	}
	IT it=begin;
	++it;
	if(p!=begin && p!=it)
		sort(begin,p,cmp);
	it=p;
	++it;
	if(it!=end && it!=last)
		sort(it,end,cmp);
}
//以上代码模拟容器
//------------------------
//以下代码模拟普通用户
void print(string const& str, list<int>& l){
	cout << str << endl;
	typedef list<int>::iterator IT;
	for(IT it=l.begin(); it!=l.end(); ++it){
		cout << *it << ' ';
	}
	cout << endl << "---------------------" << endl;
}
//
//比较类
//
class ZJW{
public:
	bool operator()(int const& a, int const& b){
		return a > b;
	}
};
int main(){
	list<int> ls;
	for(int i=0; i<5; i++)
		ls.push_front(10+i);
	for(int i=0; i<5; i++)
		ls.push_back(100+i);
	print("添加节点后:", ls);
	ls.pop_front();
	ls.pop_back();
	print("删除头尾节点后:", ls);
		
	ls.insert(++ls.begin(),1000);//增
	print("在迭代器指向的位置添加节点后:", ls);

	ls.erase(ls.begin());//删
	print("删除迭代器指向的节点后:", ls);

	typedef list<int>::iterator IT;
	IT it = ls.begin();
	*it = 800;//改
	print("更改迭代器指向的节点后:", ls);
	
	IT fit = find(ls.begin(), ls.end(), 100);
	if(fit!=ls.end())
		ls.erase(fit);
	print("找到100并删除后:", ls);
	
//	sort(ls.begin(),ls.end());
	ZJW zjw;//比较器
	sort(ls.begin(),ls.end(),zjw);
	print("排序后:", ls);
/*
	const list<int> cls(ls);
	typedef list<int>::const_iterator CIT;
	for(CIT cit=cls.begin(); cit!=cls.end(); ++cit){
		cout << *cit << ' ';
	}
	cout << endl << "------------------" << endl;

	CIT cit = cls.begin();
//	*cit = 900; //error*/
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/63366.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

html旅游网站设计与实现——绿色古典旅游景区 HTML+CSS+JavaScript

&#x1f468;‍&#x1f393;学生HTML静态网页基础水平制作&#x1f469;‍&#x1f393;&#xff0c;页面排版干净简洁。使用HTMLCSS页面布局设计,web大学生网页设计作业源码&#xff0c;这是一个不错的旅游网页制作&#xff0c;画面精明&#xff0c;排版整洁&#xff0c;内容…

解析仓库管理系统对于企业的重要性

仓储管理的职责是有效的保存和管理仓库内的物资&#xff0c;这些物资是指仓库内所有的有形物品以及无形的资产。以前很多企业都是依靠人工方式对库房的管理&#xff0c;难免会造成一些难以解决的问题&#xff1a; 仓库种类太多&#xff0c;查看困难&#xff1b;仓库信息记录不…

Java应用程序安全框架

《从零打造项目》系列文章 工具 比MyBatis Generator更强大的代码生成器 ORM框架选型 SpringBoot项目基础设施搭建SpringBoot集成Mybatis项目实操SpringBoot集成MybatisPlus项目实操SpringBoot集成Spring Data JPA项目实操 数据库变更管理 数据库变更管理&#xff1a;Liquibase…

Word控件Spire.Doc 【图像形状】教程(11): 如何在 C# 中为 Word 中的图像设置 Transeperant 颜色

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…

A-Level经济题解析及练习Policy options for Common Resources

今日知识点&#xff1a;Policy options for Common Resources 例题 There is a medieval town where sheep graze on common land. As the population grows, the number of sheep grows. However, the amount of land is fixed, the grass begins to disappear from overgra…

SwiftUI 中为什么应该经常用子视图替换父视图中的大段内容?

概览 在 SwiftUI 官方教程中&#xff0c;Apple 时常提出“化整为零”的界面布局思想。简单来说&#xff0c;Apple 推荐 SwiftUI 视图的构建方式是&#xff1a;用若干自定义小视图来构成上层的功能视图。 这是为什么呢&#xff1f; 在本篇博文中&#xff0c;我们将用一个通俗…

[Java反序列化]—CommonsCollections6

先贴个图 0x01: CC 6 应该是CC1 和 URLDNS 的综合&#xff0c;有一定联系&#xff0c;审一下吧 JDK版本需低于 8u71 AnnotationInvocationHandler类的readObject()方法在8u71以后逻辑就发生了改变&#xff0c;不能再利用了&#xff0c;所以就需要找一个绕过高版本的利用链…

Cadence Virtuoso Layout 版图绘制的使用技巧及其相关快捷键

1.版图前准备操作 画好原理图&#xff0c;打好pin脚&#xff08;pin最好以全大写的形式书写&#xff0c;以防后续操作中可能出现Bug&#xff09; 查看所使用工艺库的design rule文件&#xff0c;确定栅格单位设置大小 在准备绘制的原理图界面启动layout XL/GXL 在layout界面…

JS 正则表达式常用方法

1. JS 正则表达式 2. 使用字符串方法 3. 使用 RegExp 方法 1. JS 正则表达式 JS 正则表达式语法: # JS 的正则表达式不需要使用引号包裹&#xff0c;PHP 需要使用引号包裹。修饰符是可选的&#xff0c;可写可不写/正则表达式主体/修饰符JS 中使用正则表达式的方法比较多&am…

【强化学习论文合集】九.2018AAAI人工智能大会论文(AAAI2018)

强化学习(Reinforcement Learning, RL),又称再励学习、评价学习或增强学习,是机器学习的范式和方法论之一,用于描述和解决智能体(agent)在与环境的交互过程中通过学习策略以达成回报最大化或实现特定目标的问题。 本专栏整理了近几年国际顶级会议中,涉及强化学习(Rein…

Python中的Apriori关联算法-市场购物篮分析

数据科学Apriori算法是一种数据挖掘技术&#xff0c;用于挖掘频繁项集和相关的关联规则。本模块重点介绍什么是关联规则挖掘和Apriori算法&#xff0c;以及Apriori算法的用法。 去年&#xff0c;我们为一家公司进行了短暂的咨询工作&#xff0c;该公司正在构建一个主要基于Apr…

使用DIV+CSS技术设计的非遗文化网页与实现制作(web前端网页制作课作业)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

m基于自适应遗传优化的IEEE-6建设费用和网络损耗费用最小化电网规划算法matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 电力工业是当今世界各国经济的重要组成部分&#xff0c;随着世界经济的不断发展&#xff0c;电网的建设和中长期规划和经济发展之间的矛盾变得越来越突出&#xff0c;对电力系统的需求也变得越来…

微服务框架 SpringCloud微服务架构 16 SpringAMQP 16.7 DirectExchange

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构16 SpringAMQP16.7 DirectExchange16.7.1 发布订阅 - DirectExchange16.7.…

基于遗传优化算法的小车障碍物避障路线规划matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 一种通过模拟自然进化过程搜索最优解的方法&#xff0c;对于一个最优化问题&#xff0c;该算法通过一定数量的候选解种群迭代地执行选择、交叉、变异、评价等操作使得种群向更好的解进化。 遗传算…

MyBatisPlus简述

文章目录一、MyBatisPlus入门案例与简介1.入门案例2.springboot整合mybatis的方式3.springboot整合mybatisplus步骤1.创建环境&#xff0c;上面我们已经创建过了步骤2.创建数据库及表步骤2.pom.xml补全依赖步骤3.添加MP的相关配置信息步骤4.根据数据库表创建实体类步骤5.创建Da…

linux安装redis哨兵

安装环境 服务器一台&#xff1a; 服务器IP&#xff1a;172.169.3.251主从端口&#xff1a;6379、6380、6381哨兵端口&#xff0c;26379、26380、26381安装目录&#xff1a;/usr/local/redis配置文件目录&#xff1a;/usr/loca/redis/conf redis安装 1、下载redis wget ht…

设计模式--策略模式

文章目录前言一、未使用设计模式二、策略模式1.定义2.结构三、应用场景四、优缺点优缺参考资料前言 需求&#xff1a; 一天&#xff0c;产品经理走过来对你说。猫啊&#xff08;自称&#xff09;&#xff0c;帮我设计一个计算器&#xff0c;需要的功能有求最大值&#xff0c;最…

【JavaEE-Servlet】Filter过滤器详解

Filter过滤器熟悉的关键字-Filter&#xff08;回顾-联系-可以不看&#xff09;Filter概述何时使用&#xff1f;Filter生命周期过滤器单个实现doFilter方法关于Filter的配置路径Filter的执行顺序在web.xml文件中进行配置的时候&#xff0c;Filter的执行顺序是什么&#xff1f;使…

HTML期末学生大作业-班级校园我的校园网页设计与实现html+css+javascript

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…