C++ 简单模拟实现 STL 中的 list 与 queue

目录

一,list

1, list 的节点与迭代器

2,list 的数据结构、一些简单的功能、构造函数

3,list 的对元素操作

4,C++ 11 的一些功能

5,完整代码:

二,queue


一,list

std::list 是 C++ 标准模板库 (STL) 中提供的一个容器模板,它被实现为环状双向链表。list 和 vector 是两个最常被使用的容器。相较于 vector 的连续线性空间,list 的非连续存储就显得复杂许多,它的好处是每次插人或删除一个元素,就配置或释放一个元素空间。因此,list 对空间的使用一点也不浪费。而且,对于任何位置的插入或移除元素,list 永远是常数时间。

关于 list 的各种接口的用法这里就不介绍了,此文主要是模拟实现。
 

1, list 的节点与迭代器

list 本身和 list 的节点是不同的结构,是需要分开设计的。list 中会包含 list 节点结构。节点结构:

template<class T>
struct list_node {
	list_node<T>* next, * pre;	// next 指向下一个节点,pre 指向前一个节点
	T data;
	list_node(const T& data_ = T())
		:next(nullptr),pre(nullptr),data(data_){}
};

如果不清楚迭代器是什么或者是不清楚要怎么设计一个容器专属的迭代器可以看看这个:C++ 迭代器与反向迭代器-CSDN博客

如果对 vector 的实现细节感兴趣可以看看这个:C++ 简单模拟实现 STL 中的 vector 与 stack-CSDN博客

list 不再能够像 vector 一样以普通指针作为迭代器,因为其节点不保证在储存空间中连续存在。所以 list 迭代器必须有能力指向 list 的节点,并且能够进行正确的递增(++)、递减(--)、取值(*)、成员存取(->)等操作。这里要注意,取值时取的是节点的数据值,不是节点本身,成员取用时取用的是节点的成员。例如:

mySTL::list<int> lt = { 1,2,3,4,5 };
for (auto it = lt.begin();it != lt.end();++it) {
	cout << *it << " ";    // 输出的是 1 2 3 4 5;
}
mySTL::list<pair<int, int>> lt2 = { {1,2},{3,4},{5,6} };
for (auto it = lt2.begin();it != lt2.end();++it) {
	cout << it->first << "," << it->second << " # ";	// 输出的是 1,2 # 3,4 # 5,6 #
}

list 迭代器的设计:

template<class T,class Ref,class Ptr>
struct list_iterator {

	typedef list_node<T> Node;
	typedef list_iterator<T, Ref, Ptr> self;
	typedef list_iterator<T, T&, T*> iterator;

	// 迭代器内部的一个普通指针类型,指向对应的 list 节点
	Node* _node;

	// 迭代器相应类型的定义
	typedef T	value_type;
	typedef Ref reference;
	typedef Ptr pointer;

	// 迭代器的构造
	list_iterator(Node* node):_node(node){}					// 用节点构造当前迭代器
	list_iterator(const iterator& iter):_node(iter._node){}	// 用普通迭代器构造当前迭代器

	// 注意, 对迭代器解引用, 取出来的是节点里面的数据值
	reference operator*()const { return _node->data; }
	// &(operator*()), 这是一个标准的做法
	pointer operator->()const { return &(operator*()); }

	self& operator++() { 
		_node = _node->next; 
		return *this;
	}
	self operator++(int){
		Node* tmp = _node;
		_node = _node->next;
		return tmp;
	}
	self& operator--() { 
		_node = _node->pre; 
		return *this;
	}
	self operator--(int) {
		Node* tmp = _node;
		_node = _node->pre;
		return tmp;
	}

	bool operator==(const self& iter)const { return _node == iter._node; }
	bool operator!=(const self& iter)const { return not operator==(iter); }

};

2,list 的数据结构、一些简单的功能、构造函数

list 是一个带有头节点的环状双向链表,它只需要一个指针就可以完整的表示整个链表,为了方便操作,我们也可以来额外来维护一个 size 变量来表示节点的个数(不包括头节点)。

template<class T>
class list {
	// ...
private:
	typedef list_node<T> Node;
	typedef list<T> self;

private:
	Node* _head = nullptr;  //头节点
	size_t _size = 0;

	void initialize() {		//初始化头节点
		_head = new Node;
		_head->pre = _head->next = _head;
	}
	// ...
};

list 中有关迭代器的操作与一些简单的基础功能:

template<class T>
class list {
	// ...
public:
	//迭代器
	/*正向迭代器*/
	typedef list_iterator<T, T&, T*> iterator;
	typedef list_iterator<T, const T&, const T*> const_iterator;

	iterator begin() { return _head->next; }
	iterator end() { return _head; }
	const_iterator begin()const { return _head->next; }
	const_iterator end()const { return _head; }

	/*反向迭代器*/
	typedef Reverse_Iterator<iterator> reverse_iterator;
	typedef Reverse_Iterator<const_iterator> const_reverse_iterator;

	reverse_iterator rbegin() { return end(); }
	reverse_iterator rend() { return begin(); }
	const_reverse_iterator rbegin()const { return end(); }
	const_reverse_iterator rend()const { return begin(); }

public:
	// 简单的基础功能
	size_t size() { return _size; }
	bool empty() { return _size == 0; }
	void clear() {
		while (not empty()) pop_back();
	}

	void swap(list& lt) {
		std::swap(_head, lt._head);
		std::swap(_size, lt._size);
	}

	// 对首尾元素的访问
	T& back() { return *(--end()); }
	const T& back()const { return *(--end()); }
	T& front() { return *begin(); }
	const T& front()const { return *begin(); }
	// ...
};

list 的构造函数:

template<class T>
class list {
	// ...
public:
	//构造
	list() { initialize(); }

	list(size_t n, const T& data = T()) {
		initialize();
		while (n--) { push_back(data); }
	}
	list(int n, const T& data = T()) {
		initialize();
		while (n--) { push_back(data); }
	}

    /*使用迭代器构造*/
	template<class input_iterator>						
	list(input_iterator begin, input_iterator end) {
		initialize();
		while (begin != end) {
			push_back(*(begin++));
		}
	}

	//拷贝
	list(const list& lt) {
		initialize();
		for (const auto& data : lt) {
			push_back(data);
		}
	}

	self& operator=(list lt) {
		swap(lt);
		return *this;
	}

	//析构
	~list() {
		clear();
		delete _head;
		_head = nullptr;
		_size = 0;
	}
	// ...
};

3,list 的对元素操作

std::list 里面提供的元素操作有很多,这里就只挑几种重要的函数来实现。我们把 insert 与 erase 操作实现之后就可以很轻松的实现 push_back()、push_front()(尾插,头插) 与 pop_back() 、pop_front() (尾删,头删)操作了。

template<class T>
class list {
	// ...
public:
	//增
	void push_front(const T& data) { insert(begin(), data); }	// 头插新节点
	void push_back(const T& data) { insert(end(), data); }		// 尾插新节点
	// 在 pos 位置的前面插入一个值为 data 的新节点, 返回新插入的节点的迭代器
	iterator insert(iterator pos, const T& data) {
		Node* node = pos._node;
		Node* newNode = new Node(data);

		newNode->next = node;
		newNode->pre = node->pre;

		node->pre->next = newNode;
		node->pre = newNode;
		++_size;
		return newNode;
	}

	//删
	void pop_front() { erase(begin()); }	// 头删
	void pop_back() { erase(--end()); }		// 尾删
	// 删掉迭代器 pos 所指向的节点, 返回删掉的节点的位置的新节点迭代器
	iterator erase(iterator pos) {
		assert(pos != end());
		Node* tmp = pos._node;
		tmp->pre->next = tmp->next;
		tmp->next->pre = tmp->pre;
		Node* res = tmp->next;
		delete tmp;
		--_size;
		return res;
	}
	// ...
};

4,C++ 11 的一些功能

这里主要实现的功能是 initializer_list 初始化右值引用,如果对这两个东西不了解的话可以看看这两篇博客:

C++11 一些常用的功能-CSDN博客

C++ 左值引用与右值引用-CSDN博客

template<class T>
class list {
	// ...
public:
	//C++ 11 
	//initializer_list构造
	list(const std::initializer_list<T>& lt) {
		initialize();
		for (const T& data : lt) {
			push_back(data);
		}
	}

	//右值引用相关
	//移动构造与移动赋值
	list(list&& lt) :_head(lt._head), _size(lt._size) {
		initialize();
		lt._head = nullptr;
		lt._size = 0;
	}

	self& operator=(list&& lt) {
		delete* this;
		std::swap(_head, lt._head);
		std::swap(_size, lt._size);
	}

	//插入
	void push_front(T&& data) { insert(begin(), std::forward<T>(data)); }
	void push_back(T&& data) { insert(end(), std::forward<T>(data)); }
	iterator insert(iterator pos, T&& data) {
		Node* node = pos._node;
		Node* newNode = new Node(std::forward<T>(data));

		newNode->next = node;
		newNode->pre = node->pre;

		node->pre->next = newNode;
		node->pre = newNode;
		++_size;
		return newNode;
	}
	// ...
};

5,完整代码:

namespace mySTL {

	// list 节点类
	template<class T>
	struct list_node {
		list_node<T>* next, * pre;	// next 指向下一个节点,pre指向前一个节点
		T data;
		list_node(const T& data_ = T())
			:next(nullptr),pre(nullptr),data(data_){}
	};

	// list 迭代器类
	template<class T,class Ref,class Ptr>
	struct list_iterator {

		typedef list_node<T> Node;
		typedef list_iterator<T, Ref, Ptr> self;
		typedef list_iterator<T, T&, T*> iterator;

		// 迭代器内部的一个普通指针类型,指向对应的 list 节点
		Node* _node;

		// 迭代器相应类型的定义
		typedef T	value_type;
		typedef Ref reference;
		typedef Ptr pointer;

		// 迭代器的构造
		list_iterator(Node* node):_node(node){}					// 用节点构造当前迭代器
		list_iterator(const iterator& iter):_node(iter._node){}	// 用普通迭代器构造当前迭代器

		// 注意, 对迭代器解引用, 取出来的是节点里面的数据值
		reference operator*()const { return _node->data; }
		// &(operator*()), 这是一个标准的做法
		pointer operator->()const { return &(operator*()); }

		self& operator++() { 
			_node = _node->next; 
			return *this;
		}
		self operator++(int){
			Node* tmp = _node;
			_node = _node->next;
			return tmp;
		}
		self& operator--() { 
			_node = _node->pre; 
			return *this;
		}
		self operator--(int) {
			Node* tmp = _node;
			_node = _node->pre;
			return tmp;
		}

		bool operator==(const self& iter)const { return _node == iter._node; }
		bool operator!=(const self& iter)const { return not operator==(iter); }

	};
	
	// list 类
	template<class T>
	class list {
	private:
		typedef list_node<T> Node;
		typedef list<T> self;

	private:
		Node* _head = nullptr;  //头节点
		size_t _size = 0;

		void initialize() {		//初始化头节点
			_head = new Node;
			_head->pre = _head->next = _head;
		}

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

		iterator begin() { return _head->next; }
		iterator end() { return _head; }
		const_iterator begin()const { return _head->next; }
		const_iterator end()const { return _head; }

		/*反向迭代器*/
		typedef Reverse_Iterator<iterator> reverse_iterator;		
		typedef Reverse_Iterator<const_iterator> const_reverse_iterator;

		reverse_iterator rbegin() { return end(); }
		reverse_iterator rend() { return begin(); }
		const_reverse_iterator rbegin()const { return end(); }
		const_reverse_iterator rend()const { return begin(); }

	public:
		// 简单的基础功能
		size_t size() { return _size; }
		bool empty() { return _size == 0; }
		void clear() { 
			while (not empty()) pop_back();
		}

		void swap(list& lt) {
			std::swap(_head, lt._head);
			std::swap(_size, lt._size);
		}

		// 对首尾元素的访问
		T& back() { return *(--end()); }
		const T& back()const { return *(--end()); }
		T& front() { return *begin(); }
		const T& front()const { return *begin(); }

		// 在迭代器 start 与 finish 构成的范围内查找值为 target 的节点
		iterator find(const iterator& start, const iterator& finish, const T& target) {
			for (iterator it = start;it != finish;++it) {
				if (*it == target) return it;
			}
			return finish;
		}

	public:
		//构造
		list() { initialize(); }

		list(size_t n, const T& data = T()) {
			initialize();
			while (n--) { push_back(data); }
		}
		list(int n, const T& data = T()) {
			initialize();
			while (n--) { push_back(data); }
		}

		template<class input_iterator>						/*使用迭代器构造*/
		list(input_iterator begin, input_iterator end) {
			initialize();
			while (begin != end) {
				push_back(*(begin++));
			}
		}

		//拷贝
		list(const list& lt) {
			initialize();
			for (const auto& data : lt) {
				push_back(data);
			}
		}

		self& operator=(list lt) {
			swap(lt);
			return *this;
		}

		//析构
		~list() {
			clear();
			delete _head;
			_head = nullptr;
			_size = 0;
		}

	public:
		//增
		void push_front(const T& data) { insert(begin(), data); }	// 头插新节点
		void push_back(const T& data) { insert(end(), data); }		// 尾插新节点
		// 在 pos 位置的前面插入一个值为 data 的新节点, 返回新插入的节点的迭代器
		iterator insert(iterator pos,const T& data) {
			Node* node = pos._node;
			Node* newNode = new Node(data);

			newNode->next = node;
			newNode->pre = node->pre;

			node->pre->next = newNode;
			node->pre = newNode;
			++_size;
			return newNode;
		}

		//删
		void pop_front() { erase(begin()); }	// 头删
		void pop_back() { erase(--end()); }		// 尾删
		// 删掉迭代器 pos 所指向的节点, 返回删掉的节点的位置的新节点迭代器
		iterator erase(iterator pos) {
			assert(pos != end());
			Node* tmp = pos._node;
			tmp->pre->next = tmp->next;
			tmp->next->pre = tmp->pre;

			Node* res = tmp->next;
			delete tmp;
			--_size;
			return res;
		}

	public:
		//C++ 11 
		//initializer_list构造
		list(const std::initializer_list<T>& lt) {
			initialize();
			for (const T& data : lt) {
				push_back(data);
			}
		}

		//右值引用相关
		//移动构造与移动赋值
		list(list&& lt) :_head(lt._head), _size(lt._size) {
			initialize();
			lt._head = nullptr;
			lt._size = 0;
		}

		self& operator=(list&& lt) {
			delete *this;
			std::swap(_head, lt._head);
			std::swap(_size, lt._size);
		}

		//插入
		void push_front(T&& data) { insert(begin(), std::forward<T>(data)); }
		void push_back(T&& data) { insert(end(), std::forward<T>(data)); }
		iterator insert(iterator pos, T&& data) {
			Node* node = pos._node;
			Node* newNode = new Node(std::forward<T>(data));

			newNode->next = node;
			newNode->pre = node->pre;

			node->pre->next = newNode;
			node->pre = newNode;
			++_size;
			return newNode;
		}

	};

}

二,queue

queue 是一种先进先出(First In First Out,FIFO)的数据结构,它有两个出口。queue 允许新增元素、移除元素、从最底端加人元素取得最顶端元素。但除了最底端可以加入、最顶端可以取出外,没有任何其它方法可以存取 queue 的其它元素。也就是说,queue 不允许有遍历行为。将元素推人queue 的操作称为 push,将元素推出 queue 的操作称为 pop。

queue 与 stack 一样,都是容器适配器(container adapters),他们的底层都是其他的容器,STL 中的 stack 与 queue 实际上都是对其他容器的封装,其都不支持迭代器。

我们可以选择用 list 也可以选择用 deque 来当作 queue 的底层容器。

namespace mySTL {

	template<class T, class Container = list<T>>
	class queue {
	private:
		Container _cont;	// 底层使用的容器
	public:
		void push(const T& data) { _cont.push_back(data); }
		void push(T&& data) { _cont.push_back(std::forward<T>(data)); }
		void pop() { _cont.pop_front(); }

		T& back() { return _cont.back(); }
		const T& back()const { return _cont.back(); }
		T& front() { return _cont.front(); }
		const T& front()const { return _cont.front(); }

		size_t size() { return _cont.size(); }
		bool empty() { return _cont.empty(); }

	};

}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

织梦地方php分类信息源码带数据库【附下载】

织梦地方&#xff08;DedeCMS&#xff09;是一款基于PHPMySQL技术的开源内容管理系统&#xff08;CMS&#xff09;。它以其强大的功能、灵活的扩展性和友好的用户界面&#xff0c;成为了众多网站建设者的首选。 在功能方面&#xff0c;织梦地方CMS提供了丰富的模板标签和灵活的…

问卷调查数据分析指南!掌握方法,精准把握用户需求!

“我们可以用自定义报表、交叉报表、自定义过滤器等放方式进行问卷调查数据分析。“ 问卷调查的过程中&#xff0c;问卷设计、问卷分发、问卷收集可能都不是让我们最头疼的。经过几天的奋战&#xff0c;终于拿到了数据&#xff0c;但是问题也随之而来。收集上来的问卷信息&…

word文件如何转PDF格式?word转PDF的方法

在当今数字化时代&#xff0c;文档格式的转换已成为日常生活和工作中不可或缺的一部分。其中&#xff0c;将Word文档转换为PDF格式更是受到了广大用户的青睐。本文将详细介绍Word转PDF的方法&#xff0c;帮助读者轻松实现文档格式的转换&#xff0c;并探讨转换过程中的注意事项…

03-CSS盒模型(padding、margin、opactiy、cursor、display、css3前缀)

一、CSS盒模型 CSS 盒模型规定了处理元素内容、内边距、边框 和 外边距 的方式。最内部分是元素内容&#xff0c;直接包围内容的是内边距。内边距呈现了元素的背景。内边距的边缘是边框。边框以外是外边距。 1.元素的尺寸: height 设置元素的高度。属性值&#xff1a;auto&am…

用BI来做金蝶的数据分析,真能随时自助分析?

BI数据分析快的事&#xff0c;大家都知道&#xff0c;那用BI来分析金蝶ERP上的数据也很快&#xff0c;也能随时想怎么分析就怎么分析&#xff0c;想分析哪些数据就分析哪些数据吗&#xff1f; 用BI分析金蝶数据&#xff0c;不仅可随时自助分析&#xff0c;还可极大提高分析效率…

Nginx 内存池

目录 零、基本框架 一、基础结构 二、对外接口 三、函数实现 1、ngx_create_pool 2、ngx_destroy_pool 3、ngx_reset_pool 4、ngx_palloc 5、ngx_pnalloc 6、ngx_pmemalign 7、ngx_pfree 8、ngx_pcalloc 9、ngx_pool_cleanup_add 10、ngx_pool_run_cleanup_file…

Flask python 开发篇:上传文件(在指定目录下创建文件夹)

flask上传文件以及常见问题 一、flask文档上传文件的介绍二、上传文件的实现2.1、生成一个from表单&#xff0c;用来提交图片2.2、编写上传的逻辑 三、运行代码、以及常见异常四、写在最后 一、flask文档上传文件的介绍 Flask上传文件的文档介绍&#xff0c;文件上传的基本思想…

基于nodejs+vue的nuct产品售后管理系统python-flask-django-php

同时还能为用户提供一个方便实用的nuct产品售后管理系统&#xff0c;使得用户能够及时地找到合适自己的产品。管理员在使用本系统时&#xff0c;可以通过后台管理员界面管理用户的信息&#xff0c;也可以发布产品售后信息&#xff0c;让用户及时了解nuct产品售后信息。这样&…

web前端之3D标签动画、指定范围的随机数、动态设置css变量、文档片段对象、反向动画

MENU 效果图htmlJavaScriptstyle 效果图 html <div class"container"></div>JavaScript // 祝词 var words [健康码常绿,股票飙红,生意兴隆,财源广进,心想事成,永远十八,身体健康,大富大贵,大吉大利,万事如意,美梦成真,吉祥如意,鸿运当头,五福临门,吉…

uniapp的配置文件、入口文件、主组件、页面管理部分

pages.json 配置文件&#xff0c;全局页面路径配置&#xff0c;应用的状态栏、导航条、标题、窗口背景色设置等 main.js 入口文件&#xff0c;主要作用是初始化vue实例、定义全局组件、使用需要的插件如 vuex&#xff0c;注意uniapp无法使用vue-router&#xff0c;路由须在pag…

每日一练:LeeCode-200、岛屿数量【DFS递归+BFS队列】

给你一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的的二维网格&#xff0c;请你计算网格中岛屿的数量。 岛屿总是被水包围&#xff0c;并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 此外&#xff0c;你可以假设该网格的四条边…

生物信息—数据库

文章目录 核酸数据库1 一级核酸数据库&#xff1a;GenBank1.1 原核生物核酸序列1.2 真核生物成熟mRNA1.3 真核生物DNA序列 2 一级核酸数据库&#xff1a;基因组数据库&#xff1a;Ensemble3 一级核酸数据库&#xff1a;微生物宏基因组数据库&#xff1a;JCVI4 二级核酸数据库 蛋…

蓝桥杯练习07小兔子爬楼梯

小兔子爬楼梯 介绍 小兔子想去月球上旅行&#xff0c;假设小兔子拥有一个阶梯子&#xff0c;当你爬完层就可以到达月球&#xff0c;小兔子每次可以跳1或者2个台阶&#xff0c;小兔子有多少种跳法可以到达月球呢&#xff1f; 给定n是一个正整数&#xff0c;代表梯子的阶数&…

数据可视化基础与应用-04-seaborn库从入门到精通03

总结 本系列是数据可视化基础与应用的第04篇seaborn&#xff0c;是seaborn从入门到精通系列第3篇。本系列的目的是可以完整的完成seaborn从入门到精通。主要介绍基于seaborn实现数据可视化。 参考 参考:数据可视化-seaborn seaborn从入门到精通03-绘图功能实现01-关系绘图 …

在ubuntu22.04系统上用pycharm编写第一个ros2程序

1.打开终端&#xff08;快捷键altctrlt&#xff09;&#xff0c;创建工作空间&#xff0c;工作空间就是文件夹 2.创建一个功能包 打开pycharm的终端&#xff08;altf12&#xff09; 3.创建节点文件 在village_li文件夹右键新建li4.py 4.在li4.py编写代码 5.在setup.py里面添加…

http模块 获取http请求报文中的路径 与 查询字符串

虽然request.url已包含属性和查询字符串&#xff0c;但使用不便&#xff0c;若只需其中一个不好提取&#xff0c;于是用到了如下路径和字符串的单独查询方法&#xff1a; 一、获取路径 例如&#xff1a;我在启动谷歌端口时输入http://127.0.0.1:9000 后接了 "/search?k…

一文解释python中的实例方法,类方法和静态方法作用和区别是啥?该如何使用

我们都知道 &#xff0c;python类中有三种常见的方法 &#xff0c;分别是实例方法 &#xff0c;类方法和静态方法 。那么这几个方法到底有什么作用 &#xff1f; 它们之间有什么区别 &#xff1f;该如何使用 &#xff1f; 带着这些问题 &#xff0c;下面我们就来了解下这三种方…

基于FPGA实现的自适应三速以太网

一、三速以太网 千兆以太网PHY芯片是适配百兆和十兆的&#xff0c;十兆就不管了&#xff0c;我们的设计只适应千兆和百兆。 根据上图&#xff0c;我们是可以获取当前主机网口的速率信息的。 always(posedge w_rxc_bufr) beginif(w_rec_valid d0) beginro_speed < w_rec_…

Ubuntu系统部署Inis博客结合内网穿透实现公网访问本地站点

文章目录 前言1. Inis博客网站搭建1.1. Inis博客网站下载和安装1.2 Inis博客网站测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 3. 公网访问测试总…

java一和零(力扣Leetcode474)

一和零 力扣原题 给定一个二进制字符串数组 strs 和两个整数 m 和 n&#xff0c;请你找出并返回 strs 的最大子集的长度&#xff0c;该子集中最多有 m 个 0 和 n 个 1。 示例 1&#xff1a; 输入&#xff1a;strs [“10”, “0001”, “111001”, “1”, “0”], m 5, n …