C++系统学习(STL初识容器2)

#include<iostream>
using namespace std;
#include<stack>
#include<queue>
#include<string>
#include<list>
#include<set> //含有set和multiset
#include<map>



/*stack容器
 
*先进后出  (First in First out)

*有一个出口,只有栈顶top元素才可以被外界使用
因此,栈不允许有遍历行为

入栈push
出栈pop

*/

/*stack常用接口

功能描述:栈容器常用的对外接口

构造函数:

stack<T> stk;	//stack采用模板类实现,stack对象的默认构造形式
stack<const stack &stk> ; //拷贝构造函数

赋值操作:

stack& operator=(const stack &stk);  //重载等号操作符

数据存取:

push(elem);  //向栈顶添加元素
pop();		//从栈顶移除第一个元素
top();		//返回栈顶元素

大小操作:
empty();	//判断堆栈是否为空
size();		//返回栈的大小

*/

void test_stack_01()
{
	stack<int>s;

	//入栈
	s.push(10);
	s.push(20);
	s.push(30);
	s.push(40);

	//只要栈不为空,查看栈顶,并且执行出栈操作
	while (!s.empty())
	{
		//查看栈顶元素
		cout<< "栈顶元素为:" << s.top() <<endl;

		//出栈
		s.pop();
	}

	cout << "栈的大小:" << s.size() <<endl;//全部出栈,大小为0 

}

/*queue容器

*先进先出(First in first out)

*它有两个出口 ,队头和队尾,但队头只能出 ,队尾只能进  ,不允许有遍历行为

入队: push
出队: pop


*/

/*queue常用接口

功能描述:队列容器常用的对外接口

构造函数:

queue<T> que;	//queue采用模板类实现,queue对象的默认构造形式
queue<const queue &que> ; //拷贝构造函数

赋值操作:

queue& operator=(const queue &que);  //重载等号操作符

数据存取:

push(elem);  //向队尾添加元素
pop();		//从队头移除第一个元素
back();		//返回最后一个元素
front();	//返回第一个元素

大小操作:
empty();	//判断队列是否为空
size();		//返回队列的大小

*/

class Man {
public:
	Man(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}

	string m_Name;
	int m_Age;
};
void test_queue_01()
{
	queue<Man>q;

	Man m1("唐僧", 30);
	Man m2("孙悟空",1000);
	Man m3("猪八戒",900);
	Man m4("沙僧",800);

	//入队
	q.push(m1);
	q.push(m2);
	q.push(m3);
	q.push(m4);

	cout << "队列大小为:" << q.size() << endl;

	//判断只要队列不为空,查看队头,查看队尾,出队
	while (!q.empty())
	{
		//查看队头
		 cout<<"队头元素 姓名:"<< q.front().m_Name << "  队头元素 年龄:" << q.front().m_Age << endl;

		//查看队尾
		 cout << "队尾元素 姓名:" << q.back().m_Name << "  队尾元素 年龄:" << q.back().m_Age << endl;;

		//出队
		q.pop();
	}

	cout << "队列大小为:" <<q.size() <<endl;
}

/*list容器

功能描述:将数据进行链式存储   插入删除快,遍历慢

*链表(list):是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的

*一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域

*STL中的链表是一个双向循环链表   (最后一个节点后驱记录第一个节点地址,第一个节点前驱记录最后一个节点地址)

*由于链表的存储方式不是连续的内存空间,一次链表list中的迭代器只支持前移和后移,属于双向迭代器

*重要性质:插入和删除操作都不会造成原有list迭代器的失效,这在vector是不成立的

list和vector是最常用的两个容器,各有优缺点
*/

/*list构造函数

list<T> lst;	//list采用模板类实现,对象的默认构造形式
list(beg,end);	//构造函数将[beg,end)区间中的元素拷贝给本身
list(n,elem);	//构造函数将n个elem拷贝给本身
list(const list &lst); //拷贝构造函数


*/
void printList(const list<int> &L) //为了在打印时不修改它const
{
	for (list<int>::const_iterator it = L.begin(); it != L.end(); it++)
	{
		cout<< *it <<" ";
	}
	cout<<endl;
}

void test_list_01() 
{
	//创建list容器
	list<int>L1;

	//添加数据
	L1.push_back(10);
	L1.push_back(20);
	L1.push_back(30);
	L1.push_back(40);

	//遍历容器
	printList(L1);

	//区间方式构造
	list<int>L2(L1.begin(),L1.end());
	printList(L2);

	//拷贝构造
	list<int>L3(L1);
	printList(L3);

	//n个elem
	list<int>L4(10, 100);
	printList(L4);

}

/*list 赋值和交换
 
功能描述: 给list容器进行赋值,以及交换list容器

assign(beg,end);	//将[beg,end)区间中的数据拷贝赋值给本身
assign(n,elem);		//将n个elem拷贝赋值给本身
list& operator=(const list &lst);	//重载等号操作符
swap(lst);		//将lst与本身的元素互换

*/

void test_list_value_01()
{
	list<int>L1;

	L1.push_back(10);
	L1.push_back(20);
	L1.push_back(30);
	L1.push_back(40);

	printList(L1);

	//等号赋值
	list<int>L2 = L1;
	printList(L2);

	//assign赋值
	list<int>L3;
	L3.assign(L1.begin(),L1.end()); 
	printList(L3);

	//assign赋值
	list<int>L4;
	L4.assign(10,100);
	printList(L4);

	cout << "交换前:"<< endl;
	printList(L1);
	printList(L4);
	L1.swap(L4);

	cout<< "交换后:"<< endl;
	printList(L1);
	printList(L4);


}

/*list大小的操作

empty();   //判断容器是否为空
size();		//返回容器中元素的个数
resize(int num)	//重新指定容器的长度num,若容器变长,则以默认值填充新位置
				//如果容器变短,则末尾超出容器长度的元素被删除

resize(int num,elem) //重新指定容器的长度num,若容器变长,则以elem填充新位置
					 //如果容器变短,则末尾超出容器长度的元素被删除
*/

void test_list_capacity_01()
{
	list<int>L1;

	L1.push_back(10);
	L1.push_back(20);
	L1.push_back(30);
	L1.push_back(40);

	printList(L1);

	if (L1.empty())
	{
		cout<< "L1为空"<<endl;
	}
	else 
	{
		cout << "L1不为空" << endl;
		cout << "L1元素个数:" <<  L1.size()<<endl;
	}

	//重新指定大小
	L1.resize(10, 10000);
	printList(L1);

	L1.resize(2);
	printList(L1);
}

/*list插入和删除

push_back(elem);		//在容器尾部加入一个元素
pop_back();				//删除容器中最后一个元素
push_front(elem);		//在容器开头插入一个元素
pop_front();			//从容器开头移除一个元素
insert(pos,elem);		//在pos位置插入元素elem的拷贝,返回新数据的位置
insert(pos,n,elem);		//在pos位置插入n个元素elem的拷贝,无返回值
insert(pos,beg,end);	//在pos位置插入[beg,end)区间的数据,无返回值
clear();	//移除容器的所有数据
erase(beg,end);	//删除[beg,end)区间的数据,返回下一个数据的位置
erase(pos);		//删除pos位置的数据,返回下一个数据的位置
remove(elem);	//删除容器中所有与elem值匹配的元素


*/

void test_list_insert_delete_01()
{

	list<int>L1;

	L1.push_back(10);
	L1.push_back(20);
	L1.push_back(30);

	L1.push_front(100);
	L1.push_front(200);
	L1.push_front(300);

	printList(L1);//300 200 100 10 20 30

	//尾部删除
	L1.pop_back();
	L1.pop_front();
	printList(L1);//200 100 10 20

	//头部插入
	list<int>::iterator it = L1.begin();
	L1.insert(++it,1000);//偏移后插入
	printList(L1);//200 1000 100 10 20

	//删除
	it = L1.begin();
	L1.erase(++it);//偏移后删除
	printList(L1);//200 100 10 20

	//移除
	L1.push_back(10000);
	L1.push_back(10000);
	L1.push_back(10000);
	L1.push_back(10000);
	printList(L1); //200 100 10 20 10000 10000 10000 10000
	L1.remove(10000);
	printList(L1); //200 100 10 20

	//清空
	L1.clear();
	printList(L1); 

	
}

/*list数据存取

front();	//返回第一个元素
back();		//返回最后一个元素

list容器不能用[]或at方式访问
*/

void test_list__find()
{
	list<int>L1;

	L1.push_back(10);
	L1.push_back(20);
	L1.push_back(30);
	L1.push_back(40);

	//L1[0]  不可以用[] 访问list容器中的元素

	//L1.at(0) 不可以用at方式访问list容器中的元素

	//原因是list本质是链表,不是连续线性空间存储数据,迭代器也是不支持随机访问的

	cout << "第一个元素:" << L1.front()<<endl;
	cout<< "最后一个元素:" << L1.back() <<endl;

	//验证迭代器是不支持随机访问的
	list<int>::iterator it = L1.begin();

	//it = it + 1; //错误,没有与这些操作数匹配的“+”运算符  ,验证不支持随机访问
	it++;//可以往前或往后走  ,验证支持双向   it++,it--   ,(同理可验证其他容器)
}

/*list容器反转和排序

功能描述:将容器中的元素反转,以及将容器中的数据进行排序

reverse();//反转链表
sort();	//链表排序

*/

bool myCompare(int value1,int value2)//回调函数
{
	//降序 就让第一个数 > 第二个数
	return value1 > value2;
}

void test_list_reverse_01()
{
	list<int>L1;
	L1.push_back(20);
	L1.push_back(10);
	L1.push_back(50);
	L1.push_back(40);
	L1.push_back(30);

	cout<< "反转前:"<<endl;
	printList(L1);

	//反转
	cout << "反转后:" << endl;
	L1.reverse();//成员函数
	printList(L1);


	//排序

	cout << "排序前:" << endl;
	printList(L1);

	//所有不支持随机访问迭代器的容器,不可以用标准算法
	//不支持随机访问迭代器的容器,内部会提供一些算法

	L1.sort();//默认升序 从小到大
	cout << "排序后:" << endl;
	printList(L1);

	L1.sort(myCompare); //通过自己写的函数,让sort变成降序,从大到小


}

/*排序案例

案例描述: 将Person自定义数据类型进行排序,Person中属性有姓名、年龄、身高
排序规则:按照年龄进行升序,如果年龄相同按照身进行降序


*/
class Person {
public:
	Person(string name,int age,int height)
	{
		this->m_Name = name;
		this->m_Age = age;
		this->m_Height = height;
	}

	int m_Age;
	string m_Name;
	int m_Height;
};

//指定排序规则,自己写回调函数
bool comparePerson(Person& p1, Person& p2)
{
	//按照年龄 升序
	if (p1.m_Age == p2.m_Age)//高级排序
	{
		return p1.m_Height > p2.m_Height;
	}
	return p1.m_Age < p2.m_Age;
}

void test_list_example()
{
	list<Person>L;

	Person p1("刘备",35 ,175 );
	Person p2("曹操",45 ,180 );
	Person p3("孙权",40 ,170 );
	Person p4("赵云",25 ,190 );
	Person p5("张飞",35 ,160 );
	Person p6("关羽",35 ,200 );

	//插入数据
	L.push_back(p1);
	L.push_back(p2);
	L.push_back(p3);
	L.push_back(p4);
	L.push_back(p5);
	L.push_back(p6);

	for (list<Person>::iterator it = L.begin(); it != L.end(); it++)
	{
		cout<<"姓名:" << (*it).m_Name  << "年龄:"<< (*it).m_Age <<"身高:" << (*it).m_Height <<endl;
	}

	//排序
	cout << "--------------------------" << endl;
	cout<< "排序后:" <<endl;

	L.sort(comparePerson);
	for (list<Person>::iterator it = L.begin(); it != L.end(); it++)
	{
		cout << "姓名:" << (*it).m_Name << "年龄:" << (*it).m_Age << "身高:" << (*it).m_Height << endl;
	}
}

/* set / multiset 容器   //包含一个set头文件就可以用两种

*简介:所有元素都会在插入时自动排序

*本质:set / multiset 容器属于关联式容器,底层结构是二叉树实现

*set/multiset 的区别:

set不允许容器中有重复的元素
multiset允许容器中有重复的元素

*/

/*set容器的构造和赋值

功能描述:创建set容器以及赋值

构造:

set<T> st //默认构造函数
set<const set &st>; //拷贝构造函数

赋值:
set & operator=(const set &st);	//重载等号操作符

*/

void printSet(set<int> &s)
{
	for (set<int>::iterator it = s.begin(); it != s.end(); it++)  //用迭代器
	{
		cout<< *it <<" ";
	}
	cout << endl;
}

void test_set_01()
{
	set<int>s1;
	//插入数据只有insert方式
	s1.insert(10);
	s1.insert(40);
	s1.insert(20);
	s1.insert(30);
	s1.insert(30);

	//遍历容器
	//set容器特点:所有元素插入时候被自动排序
	//set容器不允许插入重复值,不会报错,但无效插入
	printSet(s1);

	//拷贝构造
	set<int>s2(s1);
	printSet(s2);

	//赋值
	set<int>s3(s2);
	printSet(s3);

}

/*set大小和交换


size();	     //返回容器中元素的数目
empty();	//判断容器是否为空
swap(st);	//交换两个集合容器


*/


void test_set_capacity_01() 
{
	set<int>s1;
	s1.insert(10);
	s1.insert(20);
	s1.insert(30);
	s1.insert(40);

	printSet(s1);

	//判断是否为空
	if (s1.empty())
	{
		cout<< "s1为空" <<endl;
	}
	else 
	{
		cout << "s1不为空" << endl;
		cout << "s1的大小:" << s1.size() << endl;

	}

	set<int>s2;
	s2.insert(40);//set自动排序
	s2.insert(30);
	s2.insert(20);
	s2.insert(10);
	s2.insert(50);


	cout << "交换前" << endl;
	printSet(s1);
	printSet(s2);

	s2.swap(s1);
	cout << "交换后" << endl;
	printSet(s1);
	printSet(s2);


}


/*set插入和删除
insert(elem);	//在容器中插入元素
clear();		//清除所有元素
erase(pos);		//删除pos迭代器所指的元素,返回下一个元素的迭代器
erase(beg,end);	//删除区间[beg,end)的所有元素,返回下一个元素的迭代器
erase(elem);	//删除容器中值为elem的元素

*/

void test_set_insert_delete_01()
{
	set<int>s1;
	s1.insert(10);
	s1.insert(20);
	s1.insert(30);
	s1.insert(40);

	printSet(s1);

	//删除
	s1.erase(s1.begin());
	printSet(s1);

	//删除重载版本
	s1.erase(30);
	printSet(s1);

	//清空
	//s1.erase(s1.begin(),s1.end());
	s1.clear();
	printSet(s1);

}

/*set查找和统计

find(key);	//查找key是否存在,若存在,返回该键的元素的迭代器,若不存在,返回set.end()
count(key);	//统计key元素的个数

*/

void test_find_01()
{
	set<int>s1;
	s1.insert(10);
	s1.insert(20);
	s1.insert(30);
	s1.insert(40);

	set<int>::iterator pos = s1.find(30);

	if (pos != s1.end())
	{
		cout<< "找到元素: "<< *pos << endl;
	}
	else
	{
		cout << "未找到元素 " << endl;
	}

	int num = s1.count(30);
	//对于set而言,结果要么0,要么1
	cout << "num =  " << num <<endl;

}

/*set与multise区别

multise允许插入重复值,set不允许
set插入数据的同时会返回插入结果,表示插入是否成功
multise不会检测数据,因此可以插入重复数据

*/

void test_different_01()
{
	set<int>s1;
	pair<set<int>::iterator ,bool> ret = s1.insert(10);   //返回值bool型     **等式赋值过程中执行了s1的插入
	
	if (ret.second)
	{
		cout<<"第一次插入成功" <<endl;
	}
	else
	{
		cout << "第一次插入失败" << endl;
	}

	ret = s1.insert(10);//第二次插入
	if (ret.second)//返回值
	{
		cout << "第二次插入成功" << endl;
	}
	else
	{
		cout << "第二次插入失败" << endl;
	}

	multiset<int>ms;
	ms.insert(10);
	ms.insert(10);
	ms.insert(10);
	ms.insert(10);

	for (multiset<int>::iterator it = ms.begin(); it != ms.end(); it++)
	{
		cout<< *it << " " ;
	}
	cout<<endl;
}

/*pair对组创建   不需要头文件

*功能描述:成对出现的数据,利用对组可以 返回两个数据

两种创建方式:
pair<type,type> p (value1,value2);
pair<type,type> p = make_pair(value1,value2);

*/

void test_pair_01()//记住一种即可
{
	//第一种方式
	pair<string, int>p("Tom",20);

	cout<< "姓名:" << p.first << "年龄:"<< p.second<<endl;

	//第二种方式
	pair<string, int>p2 = make_pair("Jerry", 10);

	cout << "姓名:" << p2.first << "年龄:" << p2.second << endl;

}

/*set容器排序

set容器默认排序从小到大

利用仿函数,可以改变排序规则

*/
class Mycompare {
public:
	bool operator()(int v1 ,int v2) const  //operator()重载的符合 ,第二个(前一个,后一个)放参数比较(看比较数据的类型) 
	{
		return v1 > v2;//前面的数大于后面的数
	}


};
void test_change_sort_01()
{
	set<int>s1;
	s1.insert(50);
	s1.insert(40);
	s1.insert(10);
	s1.insert(20);
	s1.insert(30);

	for (set<int>::iterator it = s1.begin(); it != s1.end(); it++)  // <int>
	{
		cout << *it << " ";
	}
	cout << endl;
	/*  C3848  在仿函数中加入const  解决
	//指定排序规则为从大到小  
	set<int,Mycompare>s2;   //仿函数本质是一个类型 
	
	s2.insert(10);
	s2.insert(40);
	s2.insert(20);
	s2.insert(50);
	s2.insert(30);
	
	for (set<int, Mycompare>::iterator it = s2.begin(); it != s2.end(); it++)  //<int, Mycompare>
	{
		cout << *it << " ";
	}
	cout << endl;
	*/
}
//set容器排序,存放自定义数据类型
class Person_1 {
public:
	Person_1(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}

	int m_Age;
	string m_Name;

};

class comparePerson_1 {

public:
	bool operator()(const Person_1& p1, const Person_1& p2)const
	{
		//按照年龄 降序
		return p1.m_Age > p2.m_Age;
	}


};

void test_sort_02()
{
	//自定义的数据类型 都要指定排序规则  写仿函数
	set<Person_1, comparePerson_1>s;

	Person_1 p1("刘备", 24);
	Person_1 p2("关羽", 28);
	Person_1 p3("张飞", 25);
	Person_1 p4("赵云",21);

	s.insert(p1);
	s.insert(p2);
	s.insert(p3);
	s.insert(p4);

	for (set<Person_1, comparePerson_1>::iterator it = s.begin();it != s.end();it++)  //类自创类型
	{
		cout<< "姓名:" << it->m_Name << "  年龄:" << it ->m_Age <<endl;
	}

}

/*map/multimap容器构造和赋值       使用频率次高

简介: 
map中所有元素都是pair
pair中的第一个元素为key(键值),起到索引作用,第二个元素为value(实值)		
所有元素都会根据元素的键值自动排序

本质:
map/multimap  属于关联式容器,底层结构是二叉树实现

优点:

可以根据key值快速找到value值

map和multimap区别

map不允许容器中有重复的key值元素   (value都允许重复)
multimap允许容器中有重复的key值元素

*/

void printMap(map<int, int> &m)
{
	for (map<int,int>::iterator it = m.begin();it != m.end();it++)
	{
		cout<<  "key = " << (*it).first <<  " value = " << it->second << endl;   //用 (*it).  或 it->
	}
	cout<<endl;
}

void test_map_01()
{	
	//创建map容器
	map<int, int>m;

	m.insert(pair<int, int>(1, 10));
	m.insert(pair<int, int>(3, 30));
	m.insert(pair<int, int>(2, 20));
	m.insert(pair<int, int>(4, 40));

	printMap(m);   // 会按照key做排序        key 1 , 2 , 3 ,4

	//拷贝构造
	map<int, int>m2(m);
	printMap(m2);

	//赋值
	map<int, int>m3;
	m3 = m2;
	printMap(m3);


}
/*map大小和交换

size();		//返回容器中元素的数目
empty();	//判断容器是否为空
swap(m);	//交换两个集合容器

*/

void test_map_size_01()
{
	map<int, int>m;

	m.insert(pair<int, int>(1, 10));
	m.insert(pair<int, int>(2, 20));
	m.insert(pair<int, int>(3, 30));

	if (m.empty())
	{
		cout<< "m为空 "<<endl;
	}
	else
	{
		cout << "m不为空 " << endl;
		cout << "m的大小为: " <<  m.size() <<endl;

	}

	map<int, int>m2;
	m2.insert(pair<int, int>(4, 100));
	m2.insert(pair<int, int>(5, 200));
	m2.insert(pair<int, int>(6, 300));

	cout << "交换前 " << endl;
	printMap(m);
	printMap(m2);

	m.swap(m2);
	cout << "交换后 " << endl;
	printMap(m);
	printMap(m2);


}

/*map插入和删除

insert(elem);	//在容器中插入元素
clear();
erase(pos);		//删除pos迭代器所指的元素,返回下一个元素的迭代器
erase(beg,end);	//删除区间[beg,end)的所有元素,返回下一个元素的迭代器
erase(key);		//删除容器中值为key的元素

*/

void test_insert_delete_01()
{
	map<int, int>m;

	//插入
	//第一种
	m.insert(pair<int, int>(1, 10));

	//第二种
	m.insert(make_pair(2, 20));//记第一、二种好记  

	//第三种
	m.insert(map<int, int>::value_type(3, 30));//map作用域下的值类型

	//第四种   []用于key找到value 
	m[4] = 40;  //最简单,但不建议[]   

	printMap(m);

	//*  cout<< m[5] <<endl;//若插错了或写一个不存在的key ,没赋值的位置会创建一个0   

	//删除
	m.erase(m.begin());
	printMap(m);

	m.erase(3);//只会按照key删   m.erase(30)没有key为30 无效
	printMap(m);

	//m.erase(m.begin(),m.end());
	m.clear();
	printMap(m);
}

/*map查找和统计

find(key)	//查找key是否存在,若存在,返回该键的元素的迭代器,若不存在,返回set.end();
count(key); //统计key的元素个数

*/

void test_map_count_01()
{
	//查找
	map<int, int>m;
	m.insert(pair<int, int>(1, 10));
	m.insert(pair<int, int>(2, 20));
	m.insert(pair<int, int>(3, 30));
	m.insert(pair<int, int>(3, 40));

	map<int, int>::iterator pos = m.find(3);

	if (pos != m.end())
	{
		cout<<"查找到了元素 key = " << (*pos).first<< " value = "<< pos->second <<endl;
	}
	else 
	{
		cout<< "未找到元素"<<endl;
	}

	//统计
	//map不允许插入重复的key   ,count结果而言 要么是0,要么是1
	//multimap  允许相同key重复插入
	int num = m.count(3);
	cout << "num = " << num <<endl;   

}
/*map容器排序

*map容器默认排序规则为 按照key值进行 从小到大排序 掌握如何改变排序规则

主要技术点:
*利用仿函数,可以改变排序规则

*/
class Mycompare_sort {
public:
	bool operator()(int v1, int v2)const   //C3848 加const   
	{
		//降序
		return v1 > v2;
	}

};


void test_map_sort_01()
{
	map<int, int ,Mycompare_sort>m;
	m.insert(pair<int, int>(1, 10));
	m.insert(pair<int, int>(2, 20));
	m.insert(pair<int, int>(3, 30));
	m.insert(pair<int, int>(4, 40));
	m.insert(pair<int, int>(5, 50));

	for (map<int, int, Mycompare_sort>::iterator it = m.begin(); it != m.end(); it++)
	{
		cout<< "key = " << it->first << " value = "<< it->second <<endl;
	}
}


int main() 
{
	//cout<< <<endl;

	test_map_sort_01();
	return 0;
}



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值