C++ 利用容器适配器,仿函数实现栈,队列,优先级队列(堆),反向迭代器,deque的介绍与底层

C++ 利用容器适配器,仿函数实现栈,队列,优先级队列【堆】,反向迭代器,deque的介绍与底层

  • 一.容器适配器的介绍
  • 二.利用容器适配器实现栈和队列
    • 1.stack
    • 2.queue
  • 三.仿函数介绍
    • 1.什么是仿函数
    • 2.仿函数的使用
    • 3.函数指针的使用
      • 1.函数指针的用处
      • 2.利用函数指针完成回调
      • 3.利用仿函数完成回调
    • 4.仿函数的玩法
      • 1.取出Key/Key-Value模型中的Key
      • 2.自定义排序
  • 四.利用容器适配器和仿函数实现优先级队列
  • 五.利用正向迭代器作为适配器实现反向迭代器
    • 1.STL库里面的实现逻辑
      • 1.rbegin和rend的实现
    • 2.反向迭代器的实现
    • 3.画图模拟反向迭代器具体的遍历流程
      • 1.vector
      • 2.list
    • 4.具体实现
    • 5.对于list的适用
    • 6.对于vector的适用
    • 7.const_reverse_iterator的实现
    • 8.验证
      • 1.list
      • 2.vector
  • 六.deque的介绍
  • 七.deque的底层原理

一.容器适配器的介绍

适配器是一种设计模式(所谓的设计模式就是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结,是很多大佬的编程的过程中总结下来的经验,类似于"武林秘籍"),
该种模式是将一个类的接口转换成客户希望的另外一个接口。

我们来看一下STL库中stack的源码,了解一下容器适配器模式到底是什么
在这里插入图片描述
下面就让我们借助容器适配器来实现一下栈和队列吧
实现之后大家就会对容器适配器模式有更加深刻的理解

二.利用容器适配器实现栈和队列

1.stack

#pragma once
//容器适配器:vector可以,list可以,deque也可以,库里面默认使用deque
namespace wzs
{template<class T, class Container = deque<T>>class stack{public://直接使用编译器默认生成的默认成员函数即可void push(const T& x){_con.push_back(x);}void pop(){_con.pop_back();}T& top(){return _con.back();}const T& top()const{return _con.back();}size_t size()const{return _con.size();}bool empty()const{return _con.empty();}private:Container _con;};
}

可见,非常的easy
就是容器的复用而已
对于stack而言
它的适配器必须满足:
push_back,pop_back,back,size,empty这几个接口
因此stack的适配器可以是
vector
list
deque中的任何一个
在这里插入图片描述
验证完毕

2.queue

#pragma once
//容器适配器:list可以,deque也可以,库里面是deque,不过vector不可以,因为vector没有头删这个接口
namespace wzs
{template<class T, class Container = deque<T>>class queue{public://使用编译器默认生成的默认成员函数即可void push(const T& x){_con.push_back(x);}void pop(){_con.pop_front();}T& back(){return _con.back();}const T& back()const{return _con.back();}T& front(){return _con.front();}const T& front()const{return _con.front();}size_t size()const{return _con.size();}bool empty()const{return _con.empty();}private:Container _con;};
}

可见,非常的easy
就是容器的复用而已
对于queue而言
它的适配器必须满足:
push_back,pop_front,back,front,size,empty这几个接口
因此stack的适配器可以是
list
deque中的任何一个
而vector因为没有pop_front这个接口,因此不能作为queue的适配器
在这里插入图片描述
验证完毕

三.仿函数介绍

1.什么是仿函数

仿函数,又叫做函数对象,它是一个类
只不过这个类重载了operator()这个运算符,使得这个类实例化出的对象在调用operator()这个函数时使用起来特别像一个函数,
也就是说这个类实例化出的对象能够像函数一样调用,因此这个类被称为仿函数

下面给大家演示一下
这是比较两个T类型的大小
在这里插入图片描述
只要一个类重载了operator(),这个类就是一个仿函数类
这个类实例化出的对象就能像函数一样进行调用

2.仿函数的使用

算法库里面的sort函数就使用了仿函数
在这里插入图片描述
默认情况下sort是排升序的
如果我们想要排降序呢?
就要用到仿函数了
我们来演示一下,顺便学习一下仿函数的语法和特性

默认排升序
在这里插入图片描述
排降序
在这里插入图片描述
sort的第三个参数要求传入仿函数对象,所以可以这样做
在这里插入图片描述
其实我们也可以自己实现一个仿函数
一般来说仿函数写出来就是为了给外界用的,所以定义成class的话要加public访问限定符调整成公有成员
不过也可以直接用struct定义这个类,毕竟struct定义的类的访问限定符默认就是public

template<class T>
struct greater
{bool operator()(const T& a, const T& b){return a > b;}
};

在这里插入图片描述
其实也可以直接传匿名对象,省下起名字了
在这里插入图片描述

3.函数指针的使用

1.函数指针的用处

可见仿函数是非常多功能的,那么它的用处是什么呢?
为什么C++创始人要设计仿函数这一语法呢?
仿函数是为了替代C语言当中的函数指针而出现的

我们知道函数指针是用来完成回调的,例如C语言库中的qsort函数
关于回调函数大家可以看我的这篇博客:征服C语言指针系列(3)
在这里插入图片描述
这里的比较规则就是由cmp这个函数指针来完成的

在学习堆的时候,我们曾经借助于函数指针来完成回调函数,实现无需修改具体函数的实现细节来完成大小堆的切换
数据结构-堆的实现及应用(堆排序和TOP-K问题)
在这里插入图片描述

2.利用函数指针完成回调

下面我们来演示一下使用函数指针完成回调

//返回a是否小于b
bool less1(int a, int b)
{return a < b;
}class A
{
public:A(bool (*p)(int,int)):_p(p){}//返回两个数中更小的那个数int smaller(int left, int right){if (_p(left, right)) return left;else return right;}private:bool (*_p)(int, int);
};int main()
{bool (*ptr)(int, int) = less1;A aa(ptr);cout << aa.smaller(1, 7) << endl;cout << aa.smaller(2, 5) << endl;return 0;
}

在这里插入图片描述
需要注意的是:

  1. 因为类A在回调less1这个函数时只能在类的成员函数进行
    而且可能类A的很多成员函数都需要回调less1这个函数,因此在类A当中增加了一个函数指针类型的成员变量,这个函数指针的参数类型和顺序以及返回值都需要跟less1这个函数一样

2.上面那个代码只能完成int和int的比较功能,无法完成string和string等等诸多类型的比较
并不符合泛型编程的思想

3.less1这个函数比较简单,因此这个函数指针并不复杂,可是那些很复杂的函数和类,如果使用函数指针的话…结果就让人很难受了

3.利用仿函数完成回调

下面我们来演示一下仿函数完成回调

template<class T>
class Less
{
public:bool operator()(const T& a, const T& b){return a < b;}
};template <class T,class Compare>
class A
{
public://返回两个元素中更小的那个元素const T& smaller(const T& left, const T& right){if (_cmp(left, right)) return left;else return right;}
private:Compare _cmp;
};int main()
{//注意:这里要往类模板的参数列表中传入实参//应该传入类型,而不是对象!!A<string, Less<string>> aa;cout << aa.smaller("abc", "wzs") << endl;A<int, Less<int>> ab;cout << ab.smaller(1, 8) << endl;return 0;
}

在这里插入图片描述
这样就既符合泛型编程的思想,使用起来也非常的好用了

4.仿函数的玩法

当然,仿函数的玩法是很多的,

1.取出Key/Key-Value模型中的Key

比如下面的这个例子:
这是取出一个键或者键值对当中的键
我们之前学过的二叉搜索树当中的Key模型和Key-Value模型就可以这样玩
这里是通过函数重载和类模板的缺省参数完成的
在这里插入图片描述

2.自定义排序

我们要实现一个比较算法,对不同的商品按照价格分别升序和降序排序

struct Goods
{string _name;//名称double _price;//价格int _evaluate;//评价Goods(const char* str, double price, int evaluate):_name(str), _price(price), _evaluate(evaluate){}
};//按照价格升序
struct ComparePriceLess
{bool operator()(const Goods& left, const Goods& right){return left._price < right._price;}
};//按照价格降序
struct ComparePriceGreater
{bool operator()(const Goods& left, const Goods& right){return left._price > right._price;}
};int main()
{vector<Goods> v = { { "苹果", 2.5, 5 }, { "香蕉", 3.2, 4 }, { "橙子", 2.9, 3 }, { "菠萝", 1.5, 4 } };sort(v.begin(),v.end(), ComparePriceLess());for (auto& e : v){cout << "商品名称: " << e._name << " 价格 :" << e._price << " 评价:" << e._evaluate << endl;}cout << endl;sort(v.begin(), v.end(), ComparePriceGreater());for (auto& e : v){cout << "商品名称: " << e._name << " 价格 :" << e._price << " 评价:" << e._evaluate << endl;}cout << endl;return 0;
}

在这里插入图片描述
这样就可以按照我们想要的方式自定义排序规则进行排序了
当然,仿函数也有一个缺点:使用仿函数完成回调必须要定义出一个类来,有点大材小用的感觉
因此我们以后会介绍一个C++11新增的语法:lambda表达式,它可以在这种情况下替代仿函数

四.利用容器适配器和仿函数实现优先级队列

优先级队列其实就是堆,
关于堆的知识,实现,应用,大家可以看我的这篇博客,里面有详细的介绍:数据结构-堆的实现及应用(堆排序和TOP-K问题)
头文件是<queue>
在这里插入图片描述
它也可以用容器适配器来实现
默认是大堆,要想实现小堆的话:第三个参数仿函数传入greater类

容器适配器:vector可以,deque也可以,库里面是vector
因为要能够支持下标随机访问(也就是operator[]),而且vector的operator[]的速度远高于deque

#pragma once
//priority_queue的头文件是queue
//priority_queue默认是大堆
//要想实现小堆的话:第三个参数仿函数传入greator类
//容器适配器:vector可以,deque也可以,库里面是vector
//大堆:父亲大于孩子
//小堆:父亲小于孩子
namespace wzs
{template <class T, class Container = vector<T>, class Compare = less<T> >class priority_queue{public://使用编译器默认生成的默认成员函数即可priority_queue() = default;//C++11新语法:强制生成默认构造template <class InputIterator>//迭代器区间构造priority_queue(InputIterator first, InputIterator last):_con(first, last){//先调一下迭代器区间构造,构造适配器对象_con//然后建堆即可//注意:向上调整算法建堆的时间复杂度O(N*logN)//向下调整算法建堆的时间复杂度O(N)//因此这里向下建堆for (int i = (_con.size() - 1 - 1) / 2; i >= 0; i--){adjust_down(i);}}bool empty() const{return _con.empty();}size_t size() const{return _con.size();}const T& top() const{return _con.front();}T& top(){return _con.front();}//向上调整算法void adjust_up(int child){int parent = (child - 1) / 2;while (child > 0){if (_cmp(_con[parent], _con[child])){swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}else{break;}}}void push(const T& x){//先插入数据,然后向上调整_con.push_back(x);adjust_up(_con.size() - 1);}//向下调整算法void adjust_down(int parent){int child = 2 * parent + 1;//默认跟左孩子比较int n = _con.size();while (child < n){//实际要跟右孩子比较if (child + 1 < n && _cmp(_con[child], _con[child + 1])){child++;}if (_cmp(_con[parent], _con[child])){swap(_con[parent], _con[child]);parent = child;child = 2 * parent + 1;}else{break;}}}void pop(){//先交换第一个和最后一个数据swap(_con[0], _con[_con.size() - 1]);//然后删除最后一个数据_con.pop_back();//最后向下调整adjust_down(0);}private:Container _con;Compare _cmp;};//仿函数greatertemplate<class T>struct greater{bool operator()(const T& a, const T& b){return a > b;}};
};

注意:
建小堆传入仿函数时:
因为优先级队列的类模板中规定仿函数传入类
因此不能传入对象,而且缺省参数也不支持跳着传

priority_queue<int, greater<int>> heap;//err:仿函数是第三个参数,只有在第二个参数传了之后才能传第3个参数
priority_queue<int,vector<int>, greater<int>()> heap;//err:仿函数是类模板,必须传入类型,不能传入对象
priority_queue<int, vector<int>, greater<int>> heap;//yes,正确的传法

在这里插入图片描述

五.利用正向迭代器作为适配器实现反向迭代器

下面我们来通过适配器的知识借助vector和list的正向迭代器实现它们的反向迭代器

首先要说明的是,反向迭代器是这么使用的
会反向打印这个容器中的数据
这里以vector为例,对于其他支持迭代器的容器来说也是这样的
在这里插入图片描述

1.STL库里面的实现逻辑

1.rbegin和rend的实现

在这里插入图片描述

2.反向迭代器的实现

在这里插入图片描述

3.画图模拟反向迭代器具体的遍历流程

1.vector

在这里插入图片描述

2.list

在这里插入图片描述
可见STL大佬的实现体现出了一种对称美(rbegin就是end,rend就是begin)
下面我们就来实现一下

4.具体实现

// 适配器 -- 复用
template<class Iterator, class Ref, class Ptr>
struct Reverse_iterator
{typedef Reverse_iterator<Iterator, Ref, Ptr> Self;//构造函数Reverse_iterator(Iterator it):_it(it){}Iterator _it;Ref operator*(){Iterator tmp(_it);return *(--tmp);}Ptr operator->(){return &(operator*());}//前置++Self& operator++(){--_it;return *this;}//前置--Self& operator--(){++_it;return *this;}//后置++Self& operator++(int){Self tmp(*this);--_it;return tmp;}//后置--Self& operator--(int){Self tmp(*this);++_it;return tmp;}bool operator==(const Self& s){return _it == s._it;}bool operator!=(const Self& s){return _it != s._it;}
};

5.对于list的适用

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;typedef Reverse_iterator<iterator, T&, T*> reverse_iterator;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());}//其他成员....无需改动
}

6.对于vector的适用

template<class T>
class vector
{
public:typedef T* iterator;typedef const T* const_iterator;typedef Reverse_iterator<iterator, T&, T*> reverse_iterator;/// 迭代器相关iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}reverse_iterator rbegin(){return reverse_iterator(end());}reverse_iterator rend(){return reverse_iterator(begin());}其他成员.... 无需改动

7.const_reverse_iterator的实现

关于const_reverse_iterator的实现,我们需要实现支持使用普通的reverse_iterator来构造const_reverse_iterator
因此我们需要增加一个模板参数T

template<class T,class Iterator,class Ref,class Ptr>
struct Reverse_iterator
{typedef Reverse_iterator<T, Iterator, Ref, Ptr> Self;typedef Reverse_iterator<T, Iterator, T&, T*> reverse_iterator;Iterator cur;Reverse_iterator(Iterator it):cur(it){}//支持reverse_iterator向const_reverse_iterator的构造Reverse_iterator(const reverse_iterator& it):cur(it.cur){}//运算符重载都是一样的
};

因为const迭代器中const保护迭代器指向的内容不被修改的功能是由解引用操作的返回值类型即Ref和Ptr所决定的,
因此可以在list和vector当中这么定义const_reverse_iterator
这份代码在list和vector当中都是一样的

typedef Reverse_iterator<T, iterator,const T&,const T*> const_reverse_iterator;const_reverse_iterator rbegin() const
{return const_reverse_iterator(end());
}const_reverse_iterator rend() const
{return const_reverse_iterator(begin());
}

8.验证

1.list

class AA
{
public:AA(int a = 1,int b = 2):_a(a),_b(b){}int _a;int _b;
};void TestReverseIterator()
{list<int> lt;int a[] = { 1,2,3,4,5,6,7,8,9,10 };for (auto& e : a){lt.push_back(e);}list<int>::reverse_iterator it = lt.rbegin();while (it != lt.rend()){*it -= 5;//可以修改cout << *it << " ";++it;}cout<<endl;list<AA> lt2;for (auto& e : a){lt2.push_back(AA(e,e));}list<AA>::const_reverse_iterator it2 = lt2.rbegin();while (it2 != lt2.rend()){//it2->_b -= 2;//不可修改cout << it2->_a << ":" << it2->_b << endl;++it2;}}

在这里插入图片描述
验证成功

2.vector

void TestReverseIterator2()
{vector<int> v;int a[] = { 1,2,3,4,5,6,7,8,9,10 };for (auto& e : a){v.push_back(e);}vector<int>::reverse_iterator it = v.rbegin();while (it != v.rend()){*it -= 5;//可以修改cout << *it << " ";++it;}cout<<endl;vector<AA> v2;for (auto& e : a){v2.push_back(AA(e,e));}vector<AA>::const_reverse_iterator it2 = v2.rbegin();while (it2 != v2.rend()){//it2->_b -= 2;//不可修改cout << it2->_a << ":" << it2->_b << endl;++it2;}
}

在这里插入图片描述
验证成功

六.deque的介绍

deque:双端队列,名字叫做双端队列,但是跟队列没有任何关系
在这里插入图片描述

七.deque的底层原理

deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的
deque的底层是一个指针数组
deque为了维护其“整体连续”以及随机访问的假象,所以它的迭代器就比较复杂了
在这里插入图片描述
在这里插入图片描述

通过保证每一个tmp数组的大小都是一样的,这样就能实现O(1)的operator[]了,

假设每个tmp数组的大小都是n,要查找下标为pos的元素 那么就是第pos/n个tmp数组的第pos%n个元素

对于deque来说我们了解即可,因为deque无法取代vector和list
实际并不常用

以上就是C++ 利用容器适配器,仿函数实现栈,队列,优先级队列(堆),反向迭代器,deque的介绍与底层的全部内容,希望能对大家有所帮助!

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

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

相关文章

Compose | UI组件(二) | Text() 文本组件

文章目录 Text() 简介Text() 参数说明Text() 显示文字fontSize 文字大小textAlign 文字对齐方式style 文字样式fontFamily 文字字体AnnotatedString 多样式文字maxLines 设置文本单行显示SelectionContainer 选中文字 总结 Text() 简介 显示文字的组件 Text() 参数说明 Comp…

免 费 小程序商城搭建之b2b2c o2o 多商家入驻商城 直播带货商城 电子商务b2b2c o2o 多商家入驻商城 直播带货商城 电子商务

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

cg插画设计行业怎么样,如何学习插画设计

插画设计行业是一个充满创意和艺术性的行业&#xff0c;随着数字化时代的不断发展&#xff0c;cg插画的应用范围越来越广泛&#xff0c;市场需求也在逐年增长。以下是一些关于acg插画设计行业的现状和发展趋势&#xff1a; 市场需求不断增长&#xff1a;随着广告、媒体、影视、…

HCIA学习作业二

要求&#xff1a;基于192.168.1.0/24进行合理划分&#xff0c;要求全网通 [AR3]display ip interface brief [AR3]display ip routing-table [AR1]display ip interface brief [AR1]display ip routing-table [AR2]display ip interface brief [AR2]display ip routing-tab…

Element-plus修改样式

场景 通过样式穿透修改前端element组件样式。 实现 1.button按钮 ::v-deep .el-button { border-radius: 0; border: 0; background-color: rgba(0, 194, 255) !important; color: black; } 2.form表单 ::v-deep .el-form { text-align: left; .el-form-item { text-align: lef…

Hadoop3.x源码解析

文章目录 一、RPC通信原理解析1、概要2、代码demo 二、NameNode启动源码解析1、概述2、启动9870端口服务3、加载镜像文件和编辑日志4、初始化NN的RPC服务端5、NN启动资源检查6、NN对心跳超时判断7、安全模式 三、DataNode启动源码解析1、概述2、初始化DataXceiverServer3、初始…

C# 在矩形内获取一个指定大小的矩形(两个矩形的中心点是重合的)

C# 在矩形内获取一个指定大小的矩形&#xff08;两个矩形的中心点是重合的&#xff09; 示例1&#xff1a; using System.Drawing;public class RectangleUtils {public static Rectangle GetInnerRectangle(Rectangle outerRectangle, Size innerSize){// 计算内部矩形的左上…

MySQL的数据锁表(data_locks 表)

data_locks 表显示了持有和请求的数据锁。关于哪些锁请求被哪些持有的锁阻塞的信息。 示例数据锁信息&#xff1a; mysql> SELECT * FROM performance_schema.data_locks\G *************************** 1. row ***************************ENGINE: INNODBENGINE_LOCK_ID:…

《WebKit 技术内幕》学习之十一(2):多媒体

2 视频 2.1 HTML5视频 在HTML5规范定义中&#xff0c;Web开发者可以使用“video”元素来播放视频资源。视频中有个重要的问题就是视频编码格式&#xff0c;对此&#xff0c;目前标准中包含了三种编码格式&#xff0c;它们分别是Ogg、MPEG4和WebM。其中Ogg是由Xiph.org组织开…

PyQt中的信号/槽以及纯python实现信号/槽设计模式

1.信号与槽的基本概念 在PyQt中&#xff0c;信号是一种对象间通信的机制。当某个特定事件发生时&#xff0c;一个信号被发射。槽是接收信号的方法&#xff0c;当信号被发射时&#xff0c;与之连接的槽会被调用。这种机制使得不同部分的代码能够松耦合地交流。 2.PyQt中的信号与…

【模拟算法系列】详解5道题

本文讲解模拟算法系列的5道经典题&#xff0c;在讲解题目的同时提供AC代码&#xff0c;点击题目即可打开对应OJ链接 目录 模拟算法的介绍 1、替换所有的问号 2、提莫攻击 3、 Z 字形变换 4、外观数列 5、数青蛙 模拟算法的介绍 题目中明确告诉你要干什么&#xff0c;思路…

C++ //练习 3.3 请说明string类的输入运算符和getline函数分别是如何处理空白字符的。

C Primer&#xff08;第5版&#xff09; 练习 3.3 练习 3.3 请说明string类的输入运算符和getline函数分别是如何处理空白字符的。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 解释 cin读取并忽略有效字符之前所有的空白字符&…

打开文件:内核做了什么

一.文件描述符本质 文件描述符的是一个非负整数&#xff0c;它是操作系统内核用来标识和管理打开文件的抽象概念。在 Linux 和其他类 Unix 操作系统中&#xff0c;几乎所有与文件相关的操作都是通过文件描述符来进行的。 文件描述符是操作系统内核为每个进程维护的一个表&…

ChatGPT 和文心一言 | 两大AI助手哪个更胜一筹

欢迎来到英杰社区&#xff1a; https://bbs.csdn.net/topics/617804998 欢迎来到阿Q社区&#xff1a; https://bbs.csdn.net/topics/617897397 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff…

Web开发4:单元测试

在Web开发中&#xff0c;单元测试是一种重要的开发实践&#xff0c;它可以帮助我们确保代码的质量和可靠性。通过编写和运行单元测试&#xff0c;我们可以验证代码的正确性&#xff0c;减少错误和缺陷&#xff0c;并提高代码的可维护性。本文将介绍单元测试的概念、好处以及如何…

券商既然是发行债券的人,为什么他还收中介费呢?

券商在金融市场中扮演着多种角色&#xff0c;其中发行债券只是其业务的一部分。券商作为金融中介机构&#xff0c;其主要功能是为投资者和融资者提供撮合服务&#xff0c;促进金融市场的有效运行。 当券商作为发行债券的角色时&#xff0c;它们会帮助公司或政府等机构发行债券…

Chrome 浏览器插件 runtime 字段解析

运行时 runtime 使用 chrome.runtime API 检索 Service Worker&#xff0c;返回有关 manifest.json 的详细信息监听和响应应用或扩展程序生命周期中的事件还可以使用此 API 将网址的相对路径转换为完整的一个 URL 一、权限 Runtime API 上的大多数方法都不需要任何权限 但是…

头歌C++之Switch控制语句编程实训

目录 第1关:根据输入数字判断是星期几 本关必读 本关任务 测试说明 第2关:根据输入的数值和运算符做相应运算 本关必读 本关任务 测试说明 第3关:根据输入年月计算该月份的天数 本关必读 本关任务

python写一个彩票中奖小游戏修订版本

先说规则&#xff1a; print("下面介绍双色球颜色规则:")print("一等奖,投注号码与当期开奖号码全部相同&#xff08;顺序不限&#xff0c;下同&#xff09;&#xff0c;即中奖")print("二等奖:投注号码与当期开奖号码中的6个红色球号码相同,即中奖&q…

鸿蒙开发实战-手写文心一言AI对话APP

运行环境 &#xff08;后面附有API9版本&#xff0c;可修改后在HarmonyOS4设备上运行&#xff09; DAYU200:4.0.10.16 SDK&#xff1a;4.0.10.15 IDE&#xff1a;4.0.600 在DAYU200:4.0.10.16上运行 一、创建应用 1.点击File->new File->Create Progect 2.选择模版…