【c++】list 模拟

 > 作者简介:დ旧言~,目前大二,现在学习Java,c,c++,Python等
> 座右铭:松树千年终是朽,槿花一日自为荣。

> 目标:能手撕list模拟

> 毒鸡汤:不为模糊不清的未来过分担忧,只为清清楚楚的现在奋发图强。

> 望小伙伴们点赞👍收藏✨加关注哟💕💕 

🌟前言

        前面我们已经学习了list的相关知识点,必然我们要简单的模拟一下,模拟list类比较复杂,里面掺杂了我们学习双链表的知识点,对模板的使用更加复杂,还有对c++类和对象的知识点使用起来更杂。对上面知识点忘了的小伙伴们大家先去巩固巩固,学习list那就更加轻松,那咱们走起。

 ⭐主体

这里我们就不分解成三文件啦,这里就创建两个文件List.h(头文件),Test.c(测试代码文件)

🌙list基本框架结构

list为任意位置插入删除的容器,底层为带头双向循环链表

模拟实现list,要实现下列三个类:

①、模拟实现结点类
②、模拟实现迭代器的类
③、模拟list主要功能的类


🌙list的结点的实现

list为任意位置插入删除的容器,底层为带头双向循环链表,所以每个结点都需有以下成员:

  1. 前驱指针
  2. 后继指针
  3. data值存放数据

结点类本质上是一个初始化函数,在list类中只需要一个构造函数就行。

// 初始化(结点类)
template<class T> // 模板
struct ListNode
{// 定义两个指针ListNode<T>* _next;  // 前驱指针 ListNode<T>* _prev;  // 后驱指针// 存储节点值T _data; // 初始化列表(构造函数)ListNode(const T& x = T()):_next(nullptr),_prev(nullptr),_data(x){}
};

问题解剖:为什么是ListNode<T>???

首先,C++中用struct定义时可不加struct,重点是这里用了一个类模板,类模板的类名不是真正的类型且类模板不支持自动推类型,即ListNode不是真正的类型,定义变量时ListNode<T>这种才是真正的类型,也就是用类模板定义变量时必须 指定对应的类型 。 注:结构体模板或类模板在定义时可以不加 <T>,但使用时必须加 <T>。

🌙list的迭代器类的实现

  1. 链表的物理空间是不连续的,是通过结点的指针顺次链接
  2. 不能像先前的string和vector一样直接解引用去访问其数据,
  3. 结点的指针解引用还是结点,结点指针++还是结点指针,
  4. 在string和vector的物理空间是连续的,所以这俩不需要实现迭代器类,可以直接使用。

为了能让list像vector一样解引用后访问对应节点中的值,++访问到下一个数据,我们需要单独写一个迭代器类的接口实现,在其内部进行封装补齐相应的功能,而这就要借助运算符重载来完成。 

💫基本框架

框架结构:

template<class T,class Ref,class Ptr>
struct __list_iterator
{typedef __list_node<T> Node;typedef __list_iterator<T, Ref, Ptr> Self;Node* _node;
}

①、迭代器类模板为什么有三个参数?

  1. 普通迭代器的话,一个class T参数就够了,由于const迭代器原因,需要加两个参数
  2. 两个参数名Ref(reference:引用)和Ptr(pointer:指针)

②、迭代器类是什么?

  • 迭代器类就一个节点的指针变量_node,但是因为我们要运算符重载等一系列操作,不得不把list的迭代器写成类,完成那些操作,list的迭代器才能正确的++到下一位置,解引用访问节点的值

③、节点指针和迭代器的区别?

  1. Node* cur(节点指针)  和 iterator it(迭代器),它们指向同一个节点,它们的物理地址是一样的,但是它们的类型不同。
  2. *cur是一个指针的解引用,取到的值是节点。
  3. *it是去调用迭代器的operator*,返回值是节点中存的值。
  4. 类型决定了对空间的解释权。

💫构造函数

 迭代器的构造函数只需要一个指针构造就行:

// 构造函数(初始化)
_list_iterator(Node* x):_node(x)
{}

 💫operator*

*it(调用的是函数,返回节点中的值):

// *it,返回节点的值
Ref operator*()
{return _node->_data;
}

问题解剖:返回值为什么是 Ref ???

  1. Ref是模板参数,因为迭代器类的模板参数Ref传入的要么是T&要么是const T&
  2. 为了const迭代器和普通迭代器的同时实现,意义就是一个只读,一个可读可写 

注:比如之前讲的vector的迭代器,*it(假设it是迭代器变量)就是拿到对应的值,那么list的迭代器也要同理,解引用迭代器就是为了访问对应位置的值,那么list只要通过迭代器返回对应节点的值就好了(*it,我们是就想要对应的值)

 💫operator->

// 返回节点值
Ptr operator->()
{return &_node->data;
}

问题解剖:为什么需要operator->?

  •  list存了个自定义类型的Date类,程序错误,因为我们并没有重载Date类的operator<<

若是内置类型的话才可以正常输出,那写一个operator<<重载吗?不,因为你无法确定要用哪些类,也不能每个类都写operator<<,那怎么办?我们访问Date类本质是想访问它内置类型(int)的_year、_month和_day吧,那我们不妨写个专属于自定义类型的operator->(因为内置类型只需要*it就可以直接输出了,但自定义类型不可以直接输出)

  • 利用operator->直接访问类的成员变量,而内置类型可以直接输出

故从根源上解决问题: 在迭代器中实现个operator->:

(Ptr是迭代器的模板参数,我们用来作为T*或const T*的)​​​​​​​

 💫operator前置++--与后置++--

代码实现:

// ++it
self& operator++()
{_node = _node->_next;// 返回节点return *this;
}
// it++
self operator++(int)
{// 拷贝self tmp(*this);// 向后走一个节点_node = _node->_next;// 返回return tmp;
}// --it
self& operator--()
{_node = _node->_prev;// 返回节点return *this;
}
// it--
self operator--(int)
{// 拷贝self tmp(*this);// 向前走一个节点_node = _node->prev;// 返回return tmp;
}

问题解剖:迭代器++对于list是什么意思???

  1. 迭代器++的意思就是想让其指向下一个节点
  2. --正好相反,为了区分前置和后置++(--),
  3. 我们会用函数重载,也就是多一个'没用的'参数:int,这个参数没什么用,只是为了区分++与--

💫operator==和operator!=

代码实现:

// 判断
bool operator!=(const self& s)
{return _node != s._node;
}
// 判断
bool operator==(const self& s)
{return _node == s._node;
}

问题解剖:两个迭代器怎么比较的???

  1. 迭代器中就一个成员变量_node,节点指针,只要比较当前的节点指针是否相同即可
  2. 这个操作在判断迭代器是否走到头有用(比如 it != s.end())

问题:迭代器的拷贝构造和赋值和析构函数需我们自己实现吗?

 答:不需要

  • 因为迭代器存的就是一个节点指针,而节点是属于链表list的,那么它的释放应由list来实现,那么迭代器的析构也无需我们自己写了。
  • 拷贝构造和赋值就是节点指针的拷贝和赋值,即使指向同一节点了,迭代器也不会析构,而list的析构到时候只会释放这个节点一次,不存在什么问题,即我们无需深拷贝,使用系统提供的浅拷贝即可。

🌙list类的实现

 在结点类和迭代器类都实现的前提下,就可实现list主要功能:增删等操作的实现。

💫基本框架

框架结构:

//3、链表类
template<class T>
class list
{typedef __list_node<T> Node;
public:typedef __list_iterator<T,T&,T*> iterator;typedef __list_iterator<T,const T&,const T*> const_iterator;private:Node* _head;//头结点
}

问题解剖:const_iterator(const迭代器的介绍)

  1. 我们知道const_iterator在begin()和end()中的返回值是需要用到的
  2. 其主要作用就是当迭代器只读时使用
  3. 普通迭代器和const迭代器的实现区别仅仅在于内部成员函数的返回值不同
  4. 一个是引用class Ref(T&或const T&),一个是指针class Ptr(T*或const T*)
  5. 当Ref时const T&就是const迭代器的调用,当Ref时T& 时就是普通迭代器的调用

💫构造函数

框架结构:

// 初始化函数
void empty_init()
{_head = new Node;_head->_next = _head;_head->_prev = _head;
}// 构造函数
list() // 1.
{empty_init();
}

解释:我们开辟一个头结点,这里就是一个循环双向链表。

💫begin和end

代码实现:

// 找头,这里有哨兵位
iterator begin()
{return _head->_next;
}
// 找尾,哨兵位就是尾
iterator end()
{return _head;
}//const类
const_iterator begin() const
{return _head->_next;
}
const_iterator end() const
{return _head;
}

💫拷贝构造

代码实现:

传统写法:

//拷贝构造:传统写法
list(const list<T>& lt)
{_head = new Node;//开辟一样的头结点_head->_next = _head;_head->_prev = _head;//1、用迭代器遍历/*const_iterator it = lt.begin();while (it != lt.end()){push_back(*it);++it;}*///2、范围for遍历//遍历lt1,把lt1的元素push_back到lt2里头for (auto e : lt){push_back(e);//自动开辟新空间,完成深拷贝}
}

解释:list的拷贝构造跟vector不同,它的拷贝是拷贝一个个节点(因为不连续的物理空间), 那么我们可以用迭代器拿到list的一个个节点【上面是传统写法】

现代写法:

template<class InputIterator>
list(InputIterator first, InputIterator last) {_head = new Node();_head->_next = _head;_head->_prev = _head;while (first != last) {push_back(*first);first++;}
}
/* 拷贝构造(现代写法):L2(L1) */
list(const list<T>& L) {_head = new Node();_head->_next = _head;_head->_prev = _head;list<T> tmp(L.begin(), L.end());swap(_head, tmp._head);  // 交换两个结点的指针
}

💫clear函数

代码实现:

// 销毁函数
void clear()
{// 找头iterator it = begin();// 循环while (it != end()){it = erase(it);}
}

问题解剖:it = erase(it)什么意思???

防止迭代器失效,因为erase返回的是被删除位置的下一位置,比如删除pos位置的,pos位置被删除后,这个位置的迭代器就失效了,那就无法通过++找到后面的位置了,所以我们通过erase返回值来更新一下迭代器位置,即更新到被删除位置的下一位置

💫operator=

代码实现:

        //赋值运算符重载(传统写法)//lt1 = lt3//list<T>& operator=(const list<T>& lt)//{//	if (this != &lt)//	{//		clear();//先释放lt1//		for (auto e : lt)//			push_back(e);//	}//	return *this;//}//赋值运算符重载(现代写法)// 赋值运算重载list<T>& operator=(list<T> lt){swap(lt);return *this;}

注释:套用传值传参拷贝构造完成深拷贝

💫析构函数

代码实现:

// 析构函数
~list()
{clear();delete _head;//删除除头结点以外的节点_head = nullptr;//删去哨兵位头结点}

💫insert函数

代码实现:

// insert插入函数
iterator insert(iterator pos, const T& x)
{Node* cur = pos._node; // 迭代器pos处的结点指针Node* prev = cur->_prev;Node* newnode = new Node(x); // 创建新的结点 // prev newnode curprev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;//return iterator(newnode);return newnode;
}

问题解剖:返回参数为什么是iterator???本质是为了防止迭代器失效问题

注:insert指的是插入到指定位置的前面

💫push_back 和 push_front

代码实现:

// 调用插入函数,尾插
void push_back(const T& x)
{insert(end(), x);
}
// 调用插入函数,头插
void push_front(const T& x)
{insert(begin(), x);
}

这里的尾插和头插直接调用插入函数就可以了。

💫erase函数

代码实现:

//erase
iterator erase(iterator pos)
{assert(pos != end());Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;//prev cur next//链接prev和nextprev->_next = next;next->_prev = prev;//delete删去结点,因为每一个节点都是动态开辟出来的delete cur;//返回被删除元素后一个元素的迭代器位置//return next;return iterator(next);
}

问题剖析:返回值问题???

erase的返回值,返回的是被删除位置的下一位置,库里面这么规定的,本质是因为删除元素一定会导致此位置的迭代器失效,故返回被删除位置的下一次位置可以更新迭代器。

💫pop_back 和 pop_front

代码实现:

// 调用删除函数,尾删
void pop_back()
{erase(--end());
}
// 调用删除函数,头删
void pop_front()
{erase(begin());
}

🌙完整源代码

list.h:

#pragma once#include<assert.h>
#include<iostream>namespace lyk
{// 初始化template<class T> // 模板struct ListNode{// 定义两个指针ListNode<T>* _next;  // 前驱指针 ListNode<T>* _prev;  // 后驱指针// 存储节点值T _data; // 初始化列表(构造函数)ListNode(const T& x = T()):_next(nullptr),_prev(nullptr),_data(x){}};// list迭代器template<class T,class Ref,class Ptr> // 第二个参数是引用,第三个参数是指针,防止迭代器失效struct _list_iterator{typedef ListNode<T> Node;typedef _list_iterator<T, Ref, Ptr> self;Node* _node; // 定义节点// 构造函数(初始化)_list_iterator(Node* x):_node(x){}// ++itself& operator++(){_node = _node->_next;// 返回节点return *this;}// it++self operator++(int){// 拷贝self tmp(*this);// 向后走一个节点_node = _node->_next;// 返回return tmp;}// --itself& operator--(){_node = _node->_prev;// 返回节点return *this;}// it--self operator--(int){// 拷贝self tmp(*this);// 向前走一个节点_node = _node->prev;// 返回return tmp;}// *it,返回节点的值Ref operator*(){return _node->_data;}// 返回节点值Ptr operator->(){return &_node->data;}// 判断bool operator!=(const self& s){return _node != s._node;}// 判断bool operator==(const self& s){return _node == s._node;}};// list的实现(包含各种函数实现)template<class T>class list{typedef ListNode<T> Node;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类const_iterator begin() const{return _head->_next;}const_iterator end() const{return _head;}// 初始化函数void empty_init(){_head = new Node;_head->_next = _head;_head->_prev = _head;}// 构造函数list() // 1.{empty_init();}list(list<T>& It) // 2.拷贝构造 传统写法{empty_init();// 尾插for (const auto& x : It){push_back(x);}}/* 拷贝构造(现代写法):L2(L1) */list(const list<T>& L) {_head = new Node();_head->_next = _head;_head->_prev = _head;list<T> tmp(L.begin(), L.end());swap(_head, tmp._head);  // 交换两个结点的指针}// 销毁函数void clear(){// 找头iterator it = begin();// 循环while (it != end()){it = erase(it);}}// 析构函数~list(){clear();delete _head;_head = nullptr;}// 交换void swap(list<T>& tmp){std::swap(_head, tmp._head);}// 赋值运算重载list<T>& operator=(list<T> lt){swap(lt);return *this;}// 调用插入函数,尾插void push_back(const T& x){insert(end(), x);}// 调用插入函数,头插void push_front(const T& x){insert(begin(), x);}// 调用删除函数,尾删void pop_back(){erase(--end());}// 调用删除函数,头删void pop_front(){erase(begin());}// insert插入函数iterator insert(iterator pos, const T& x){Node* cur = pos._node;Node* prev = cur->_prev;Node* newnode = new Node(x);// prev newnode curprev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;//return iterator(newnode);return newnode;}// erase删除函数iterator erase(iterator pos){assert(pos != end());Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;prev->_next = next;next->_prev = prev;delete cur;return next;}private:Node* _head;  // 头节点};void test_list1(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);list<int>::iterator it = lt.begin();while (it != lt.end()){//*it += 10;cout << *it << " ";++it;}cout << endl;for (auto e : lt){cout << e << " ";}cout << endl;}void test_list2(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);for (auto e : lt){cout << e << " ";}cout << endl;lt.push_back(5);lt.push_front(0);for (auto e : lt){cout << e << " ";}cout << endl;lt.pop_back();lt.pop_front();for (auto e : lt){cout << e << " ";}cout << endl;lt.clear();for (auto e : lt){cout << e << " ";}cout << endl;lt.push_back(10);lt.push_back(20);for (auto e : lt){cout << e << " ";}cout << endl;}void test_list3(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);for (auto e : lt){cout << e << " ";}cout << endl;list<int> copy(lt);for (auto e : copy){cout << e << " ";}cout << endl;list<int> lt1;lt1.push_back(10);lt1.push_back(20);lt1.push_back(30);lt1.push_back(40);lt = lt1;for (auto e : copy){cout << e << " ";}cout << endl;}void print_list(const list<int>& lt){list<int>::const_iterator it = lt.begin();while (it != lt.end()){//*it += 10;cout << *it << " ";++it;}cout << endl;for (auto e : lt){cout << e << " ";}cout << endl;}void test_list4(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);print_list(lt);list<int>::iterator it = lt.begin();while (it != lt.end()){*it += 10;cout << *it << " ";++it;}cout << endl;}
}

 test.cpp:

#define _CRT_SECURE_NO_WARNINGS 1// 包含头文件
#include<iostream>
#include<list>
#include<vector>
#include<algorithm>
using namespace std;#include"List.h"int main()
{lyk::test_list4();return 0;
}

  🌟结束语

       今天内容就到这里啦,时间过得很快,大家沉下心来好好学习,会有一定的收获的,大家多多坚持,嘻嘻,成功路上注定孤独,因为坚持的人不多。那请大家举起自己的小手给博主一键三连,有你们的支持是我最大的动力💞💞💞,回见。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯:C++模运算、快速幂

模运算 模运算是大数运算中的常用操作。如果一个数太大&#xff0c;无法直接输出&#xff0c;或者不需要直接输出&#xff0c;则可以对它取模&#xff0c;缩小数值再输出。取模可以防止溢出&#xff0c;这是常见的操作。 模是英文mod的音译&#xff0c;取模实际上是求余。 取…

交通管理|交通管理在线服务系统|基于Springboot的交通管理系统设计与实现(源码+数据库+文档)

交通管理在线服务系统目录 目录 基于Springboot的交通管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户信息管理 2、驾驶证业务管理 3、机动车业务管理 4、机动车业务类型管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计…

【超级干货】ArcGIS_空间连接_工具详解

帮助里对空间连接的解释&#xff1a; 根据空间关系将一个要素的属性连接到另一个要素。 目标要素和来自连接要素的被连接属性写入到输出要素类。 如上图所示&#xff0c;关键在于空间关系&#xff0c;只有当两个要素存在空间关系的时候&#xff0c;空间连接才有用武之地。 一…

方式0控制流水灯循环点亮

#include<reg51.h> //包含51单片机寄存器定义的头文件 #include<intrins.h> //包含函数_nop_&#xff08;&#xff09;定义的头文件 unsigned char code Tab[]{0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};//流水灯控制码&#xff0c;该数组被定义为全局变量 sbit…

《UE5_C++多人TPS完整教程》学习笔记15 ——《P16 会话接口委托(Session Interface Delegates)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P16 会话接口委托&#xff08;Session Interface Delegates&#xff09;》 的学习笔记&#xff0c;该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版&#xff0c;UP主&#xf…

2.12日学习打卡----初学RocketMQ(三)

2.12日学习打卡 目录&#xff1a; 2.12日学习打卡一. RocketMQ高级特性&#xff08;续&#xff09;消息重试延迟消息消息查询 二.RocketMQ应用实战生产端发送同步消息发送异步消息单向发送消息顺序发送消息消费顺序消息全局顺序消息延迟消息事务消息消息查询 一. RocketMQ高级特…

红蓝对抗:网络安全领域的模拟实战演练

引言&#xff1a; 随着信息技术的快速发展&#xff0c;网络安全问题日益突出。为了应对这一挑战&#xff0c;企业和组织需要不断提升自身的安全防护能力。红蓝对抗作为一种模拟实战演练方法&#xff0c;在网络安全领域得到了广泛应用。本文将介绍红蓝对抗的概念、目的、过程和…

【精品】关于枚举的高级用法

枚举父接口 public interface BaseEnum {Integer getCode();String getLabel();/*** 根据值获取枚举** param code* param clazz* return*/static <E extends Enum<E> & BaseEnum> E getEnumByCode(Integer code, Class<E> clazz) {Objects.requireNonN…

ASCII编码的诞生:解决字符标准化与跨平台通信的需求

title: ASCII编码的诞生&#xff1a;解决字符标准化与跨平台通信的需求 date: 2024/2/17 14:27:01 updated: 2024/2/17 14:27:01 tags: ASCII编码标准化跨平台字符集兼容性简洁性影响力 在计算机的发展过程中&#xff0c;字符的表示和传输一直是一个重要的问题。为了实现字符的…

python-自动化篇-终极工具-用GUI自动控制键盘和鼠标-pyautogui

文章目录 用GUI自动控制键盘和鼠标pyautogui 模块鼠标——记忆宫殿屏幕位置——移动地图——pyautogui.size鼠标位置——自身定位——pyautogui.position()移动鼠标——pyautogui.moveTo拖动鼠标——滚动鼠标——scroll 键盘按下键盘释放键盘 开始与结束通过注销关闭所有程序 用…

linux系统zabbix监控分布式监控的部署

分布式监控 服务器安装分布式监控安装工具安装mysql导入数据结构配置proxy端浏览器配置 zabbix server端监控到大量zabbix agent端&#xff0c;这样会使zabbix server端压力过大&#xff0c;使用zabbix proxy进行分布式监控 服务器安装分布式监控 安装工具 rpm -Uvh https://…

HTML | DOM | 网页前端 | 常见HTML标签总结

文章目录 1.前端开发简单分类2.前端开发环境配置3.HTML的简单介绍4.常用的HTML标签介绍 1.前端开发简单分类 前端开发&#xff0c;这里是一个广义的概念&#xff0c;不单指网页开发&#xff0c;它的常见分类 网页开发&#xff1a;前端开发的主要领域&#xff0c;使用HTML、CS…

网络安全威胁,如何解决缓冲区溢出攻击

目录 一、什么是网络安全 二、什么是缓冲区 三、缓冲区溢出 四、缓冲区溢出攻击的类型 一、什么是网络安全 网络安全&#xff08;Network Security&#xff09;指的是保护计算机网络及其相关设备、系统和数据免受未经授权访问、破坏、篡改、窃取或滥用的威胁和攻击。随着网…

单片机学习笔记---LCD1602

LCD1602介绍 LCD1602&#xff08;Liquid Crystal Display&#xff09;液晶显示屏是一种字符型液晶显示模块&#xff0c;可以显示ASCII码的标准字符和其它的一些内置特殊字符&#xff08;比如日文的片假名&#xff09;&#xff0c;还可以有8个自定义字符 显示容量&#xff1a;…

linux系统zabbix工具监控web页面

web页面监控 内建key介绍浏览器配置浏览器页面查看方式 监控指定的站点的资源下载速度&#xff0c;及页面响应时间&#xff0c;还有响应代码&#xff1b; web Scenario&#xff1a; web场景&#xff08;站点&#xff09;web page &#xff1a;web页面&#xff0c;一个场景有多…

Excel TEXT函数格式化日期

一. 基本语法 ⏹Excel 的 TEXT 函数用于将数值或日期格式化为指定的文本格式 TEXT(value, format_text)二. 拼接路径案例 # 将当前单元格日期格式化 "ls -ld /data/jmw/01/"&TEXT(A2,"YYYYMMDD")&""# 此处的日期, 是名称管理器里面定…

深入解析鸿蒙系统的页面路由(Router)机制

鸿蒙系统以其独特的分布式架构和跨设备的统一体验而备受瞩目。在这个系统中&#xff0c;页面路由&#xff08;Router&#xff09;机制是连接应用各页面的关键组成部分。本文将深入探讨鸿蒙系统的页面路由&#xff0c;揭示其工作原理、特点以及在应用开发中的实际应用。 1. 实现…

【每日一题】06 排序链表

问题描述 给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 求解 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* sortList(struct ListNode* head) {struct…

什么是 Flet?

什么是 Flet&#xff1f; Flet 是一个框架&#xff0c;允许使用您喜欢的语言构建交互式多用户 Web、桌面和移动应用程序&#xff0c;而无需前端开发经验。 您可以使用基于 Google 的 Flutter 的 Flet 控件为程序构建 UI。Flet 不只是“包装”Flutter 小部件&#xff0c;而是…

【数学建模】【2024年】【第40届】【MCM/ICM】【A题 七鳃鳗性别比与资源可用性】【解题思路】

我们通过将近半天的搜索数据&#xff0c;查到了美国五大湖中优势物种的食物网数据&#xff0c;以Eric伊利湖为例&#xff0c;共包含34各优势物种&#xff0c;相互之间的关系如下图所示&#xff1a; 一、题目 &#xff08;一&#xff09; 赛题原文 2024 MCM Problem A: Reso…