C++ 随笔(一)

算法基础随笔

一、数据结构

1.map

1、优点:

    (1)有序性,这是map结构最大的有点,其元素的有序性在很多应用中都会简化很多的操作。

    (2)红黑树,内部实现一个红黑树使得map的很多操作在log2n的时间复杂度下就可以实现,因此效率非常的高。

2、缺点:空间占用率高,因为map内部实现了红黑树,虽然提高了运行效率,但是因为每一个节点都需要额外保存父节点、孩子节点和红/黑性质,使得每一个节点都占用大量的空间。

3、适用处:对于那些有顺序要求的问题,用map会更高效一些。

4、map遍历

 // c++ 98    
 map<string, int>::iterator it;
 for (it = m2.begin(); it != m2.end(); it++) {
     string s = it->first;
     printf("%s %d\n", s.data(), it->second);
 }
 ​
 // c++ 11
 for(auto it : map1){
     cout << it.first <<" "<< it.second <<endl;
 }

5.插入元素

 // 定义一个map对象
 map<int, string> mapStudent;
  
 // 第一种 用insert函數插入pair
 mapStudent.insert(pair<int, string>(000, "student_zero"));
  
 // 第二种 用insert函数插入value_type数据
 mapStudent.insert(map<int, string>::value_type(001, "student_one"));
  
 // 第三种 用"array"方式插入
 mapStudent[123] = "student_first";

6.查找元素

 // find 返回迭代器指向当前查找元素的位置否则返回map::end()位置
 iter = mapStudent.find("123");
 if(iter != mapStudent.end())
        cout<<"Find, the value is"<<iter->second<<endl;
 else
    cout<<"Do not Find"<<endl;

7.删除与清空元素

//迭代器刪除
 iter = mapStudent.find("123");
 mapStudent.erase(iter);
 ​
 //用关键字刪除
 int n = mapStudent.erase("123"); //如果刪除了會返回1,否則返回0
 ​
 //用迭代器范围刪除 : 把整个map清空
 mapStudent.erase(mapStudent.begin(), mapStudent.end());
 //等同于mapStudent.clear()
2.unordered_map

1、优点:因为内部实现了哈希表,因此其查找速度非常的快。

2、缺点:哈希表的建立比较耗费时间

3、适用处:对于查找问题,unordered_map 会更加高效一些,因此遇到查找问题,常会考虑一下用unordered_map

在使用上map和unordered_map是一样的

3.priority_queue

优先队列与队列一样,只能从队尾插入元素,从队首删除元素。但是它有一个特性,就是队列中最大的元素总是位于队首,所以出队时,并非按照先进先出的原则进行,而是将当前队列中最大的元素出队。这点类似于给队列里的元素进行了由大到小的顺序排序。元素的比较规则默认按元素值由大到小排序,可以重载“<”操作符来重新定义比较规则。

和队列基本操作相同:

 top() 访问队头元素 
 ​
 empty() 队列是否为空
 ​
 size() 返回队列内元素个数
 ​
 push() 插入元素到队尾 (并排序)
 ​
 emplace() 原地构造一个元素并插入队列 
 ​
 pop() 弹出队头元素 swap 交换内容

定义:priority_queue<Type, Container, Functional>:

Type 就是数据类型,Container 就是容器类型(Container必须是用数组实现的容器,比如vector,deque等等,但不能用 list。STL里面默认用的是vector),Functional 就是比较的方式。

//升序队列
 priority_queue <int,vector<int>,greater<int> > q;
 //降序队列
 priority_queue <int,vector<int>,less<int> >q;

实例:

#include<iostream>
 #include <queue>
 using namespace std;
 int main() 
 {
     //对于基础类型 默认是大顶堆
     priority_queue<int> a;
     //等同于 priority_queue<int, vector<int>, less<int> > a;
     
     // 这里一定要有空格,不然成了右移运算符
     priority_queue<int, vector<int>, greater<int> > c;  //这样就是小顶堆
     priority_queue<string> b;
 ​
     for (int i = 0; i < 5; i++) 
     {
         a.push(i);
         c.push(i);
     }
     while (!a.empty()) 
     {
         cout << a.top() << ' ';
         a.pop();
     } 
     cout << endl;
 ​
     while (!c.empty()) 
     {
         cout << c.top() << ' ';
         c.pop();
     }
     cout << endl;
 ​
     b.push("abc");
     b.push("abcd");
     b.push("cbd");
     while (!b.empty()) 
     {
         cout << b.top() << ' ';
         b.pop();
     } 
     cout << endl;
     return 0;
 }

疑问:二叉堆实现优先队列:优先队列是基于大根堆和无序数组实现的????

4.deque

Deque(双端队列)是一种具有队列和栈的性质的数据结构。双端队列的元素可以从两端弹出,其限定插入和删除操作在表的两端进行

1.头文件

 #include <deque>

2.定义

a) deque<int>s1;  
b) deque<string>s2; 
c) deque<node>s3; /*node为结构体,可自行定义。*/

3.常用操作

//a) 构造函数
deque<int> ideq
//b)增加函数
 ideq.push_front( x):双端队列头部增加一个元素X
 ideq.push_back(x):双端队列尾部增加一个元素x
//c)删除函数
ideq.pop_front():删除双端队列中最前一个元素
ideq.pop_back():删除双端队列中最后一个元素
ideq.clear():清空双端队列中元素
//d)判断函数
ideq.empty() :向量是否为空,若true,则向量中无元素
//e)大小函数
ideq.size():返回向量中元素的个数

4.示例

#include <deque>
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
    deque<int> ideq(20); //Create a deque ideq with 20 elements of default value 0
    deque<int>::iterator pos;
    int i;

    //使用assign()赋值  assign在计算机中就是赋值的意思
    for (i = 0; i < 20; ++i)
        ideq[i] = i;

    //输出deque
    printf("输出deque中数据:\n");
    for (i = 0; i < 20; ++i)
        printf("%d ", ideq[i]);
    putchar('\n');

    //在头尾加入新数据
    printf("\n在头尾加入新数据...\n");
    ideq.push_back(100);
    ideq.push_front(i);

    //输出deque
    printf("\n输出deque中数据:\n");
    for (pos = ideq.begin(); pos != ideq.end(); pos++)
        printf("%d ", *pos);
    putchar('\n');

    //查找
    const int FINDNUMBER = 19;
    printf("\n查找%d\n", FINDNUMBER);
    pos = find(ideq.begin(), ideq.end(), FINDNUMBER);
    if (pos != ideq.end())
        printf("find %d success\n", *pos);
    else
        printf("find failed\n");

    //在头尾删除数据
    printf("\n在头尾删除数据...\n");
    ideq.pop_back();
    ideq.pop_front();

    //输出deque
    printf("\n输出deque中数据:\n");
    for (pos = ideq.begin(); pos != ideq.end(); pos++)
        printf("%d ", *pos);
    putchar('\n');
    return 0;
}
5.set

set 容器内的元素会被自动排序,set 与 map 不同,set 中的元素即是键值又是实值,set 不允许两个元素有相同的键值。不能通过 set 的迭代器去修改 set 元素,原因是修改元素会破坏 set 组织。当对容器中的元素进行插入或者删除时,操作之前的所有迭代器在操作之后依然有效。

1.头文件

#include <set> // set属于std命名域的,因此需要通过命名限定,例如using std::set;

2.定义

set<int> a; // 定义一个int类型的集合a
// set<int> a(10); // error,未定义这种构造函数
// set<int> a(10, 1); // error,未定义这种构造函数
set<int> b(a); // 定义并用集合a初始化集合b
set<int> b(a.begin(), a.end()); // 将集合a中的所有元素作为集合b的初始值

3.常规操作

###容量函数###
容器大小:st.size();
容器最大容量:st.max_size();
容器判空:st.empty();
查找键 key 的元素个数:st.count(key);

###添加函数###
在容器中插入元素:st.insert(const T& x);
任意位置插入一个元素:st.insert(iterator it, const T& x);

###删除函数###
删除容器中值为 elem 的元素:st.pop_back(const T& elem);
删除it迭代器所指的元素:st.erase(iterator it);
删除区间 [first,last] 之间的所有元素:st.erase(iterator first, iterator last);
清空所有元素:st.clear();

###访问函数###
查找键 key 是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end(): st.find(key);

4.示例

容量函数

#include <iostream>
#include <set>

using namespace std;
int main(int argc, char* argv[])
{
	set<int> st;
	for (int i = 0; i<6; i++){
		st.insert(i);
	}
	cout << st.size() << endl; // 输出:6
	cout << st.max_size() << endl; // 输出:214748364
	cout << st.count(2) << endl; // 输出:1
	if (st.empty())
		cout << "元素为空" << endl; // 未执行

	return 0;
}

添加函数

#include <iostream>
#include <set>

using namespace std;
int main(int argc, char* argv[])
{
	set<int> st;

	// 在容器中插入元素
	st.insert(4);
	// 任意位置插入一个元素
	set<int>::iterator it = st.begin();
	st.insert(it, 2);

	// 遍历显示
	for (it = st.begin(); it != st.end(); it++)
		cout << *it << " "; // 输出:2 4
	cout << endl;

	return 0;
}

删除函数

#include <iostream>
#include <set>

using namespace std;
int main(int argc, char* argv[])
{
	set<int> st;
	for (int i = 0; i < 8; i++)
		st.insert(i);

	// 删除容器中值为elem的元素
	st.erase(4);
	// 任意位置删除一个元素
	set<int>::iterator it = st.begin();
	st.erase(it);
	// 删除[first,last]之间的元素
	st.erase(st.begin(), ++st.begin());

	// 遍历显示
	for (it = st.begin(); it != st.end(); it++)
		cout << *it << " "; // 输出:2 3 5 6 7
	cout << endl;

	// 清空所有元素
	st.clear();

    // 判断set是否为空
    if (st.empty())
    	cout << "集合为空" << endl; // 输出:集合为空

	return 0;
}

访问函数

#include <iostream>
#include <set>

using namespace std;
int main(int argc, char* argv[])
{
	set<int> st;
	for (int i = 0; i < 6; i++)
		st.insert(i);
	// 通过find(key)查找键值
	set<int>::iterator it;
	it = st.find(2);
	cout << *it << endl; // 输出:2

	return 0;
}
6.string
string str;
str.push_back('s');	// 向末尾插入一个字符
str.pop_back();		// 向末尾删除一个字符
7.queue
  1. 头文件

 #include<queue>

      2. 定义

 queue<type> val;

      3. 方法

 q.empty()               如果队列为空返回true,否则返回false
 q.size()                返回队列中元素的个数
 q.pop()                 删除队列首元素但不返回其值
 q.front()               返回队首元素的值,但不删除该元素
 q.push()                在队尾压入新元素
 q.back()                返回队列尾元素的值,但不删除该元素 

       4. 示例 

#include <queue>
 #include <iostream>
 using namespace std;
  
 int main(){
   queue<int> q;
   for (int i = 0; i < 10; i++){
     q.push(i);
   }
   if (!q.empty()){
     cout << "队列q非空!" << endl;
     cout << "q中有" << q.size() << "个元素" << endl;
   }
   cout << "队头元素为:" << q.front() << endl;
   cout << "队尾元素为:" << q.back() << endl;
   for (int j = 0; j < 10; j++){
     int tmp = q.front();
     cout << tmp << " ";
     q.pop();
   }
   cout << endl;
   cout << "队头元素为:" << q.front() << endl;
   if (!q.empty()){
     cout << "队列非空!" << endl;
   }
 ​
   return 0;
 }

二、算法

1.sort函数
  • sort函数包含在头文件为#include<algorithm>的c++标准库中,调用标准库里的排序方法可以实现对数据的排序。其实STL中的sort()并非只是普通的快速排序,除了对普通的快速排序进行优化,它还结合了插入排序和堆排序。根据不同的数量级别以及不同情况,能自动选用合适的排序方法。

  • sort函数的模板有三个参数:

void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

(1)第一个参数first:是要排序的数组的起始地址。

(2)第二个参数last:是结束的地址(最后一个数据的后一个数据的地址)

(3)第三个参数comp是排序的方法:可以是从升序也可是降序。如果第三个参数不写,则默认的排序方法是从小到大排序。

实例:

#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(int a,int b);
main(){
  //sort函数第三个参数自己定义,实现从大到小
  int a[]={45,12,34,77,90,11,2,4,5,55};
  sort(a,a+10,cmp);
  for(int i=0;i<10;i++)
    cout<<a[i]<<" ";
}
//自定义函数
bool cmp(int a,int b){
  return a>b;
}

字符串的比较

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main(){
	string str1 = "ABC";
	string str2 = "ABD";
	string str3 = "ABC";
	string str4 = "CAB";
	sort(str4.begin(),str4.end());
	if(str1 == str2){
		cout <<"TRUE"<<endl;
	}
	if(str1 == str3)
		cout <<"TRUE"<<endl;
	if(str1 == str4)
		cout <<"TRUE--"<<endl;
	int m = str1.compare(str3);
	cout <<m << endl;
	string str = "abcdefgh";
	cout << str.substr(0,3) << endl;
	return 0;
} 
2.字符分割

(1).用strtok函数进行字符串分割

原型: char *strtok(char *str, const char *delim);

功能:分解字符串为一组字符串。

参数说明:str为要分解的字符串,delim为分隔符字符串。

返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。

其它:strtok函数线程不安全,可以使用strtok_r替代。

//借助strtok实现split
#include <string.h>
#include <stdio.h>
 
int main()
{
    char s[] = "Golden Global   View,disk * desk";
    const char *d = " ,*";
    char *p;
    p = strtok(s,d);
    while(p)
    {
        printf("%s\n",p);
        p=strtok(NULL,d);
    }
 
    return 0;
}

(2).用find() 和 substr() 函数进行字符串分割

功能:string的find()函数用于找出字母在字符串中的位置。

原型:int find(string str,int position)

str:是要找的元素

position:字符串中的某个位置,表示从从这个位置开始的字符串中找指定元素。可以不填第二个参数,默认从字符串的开头进行查找。

返回值为目标字符的位置,当没有找到目标字符时返回npos。

//实例
string s = "hello world!";
cout << s.find("e") << endl;
结果为:1

string s = "hello world!";
if (s.find("a") == s.npos) {
    cout << "404 not found" << endl;
}
结果为:404 not found
    
string s = "hello world!";
cout << s.find("l",5) << endl;
结果为:9
    
string s = "hello world!";
cout << "first time occur in s:"<<s.find_first_of("l") << endl; //第一次
cout << "last time occur in s:" << s.find_last_of("l") << endl; //最后一次
结果为:
first time occur in s:2
last time occur in s:9

原型:string substr ( size_t pos = 0, size_t n = npos ) const;

功能:获得子字符串。

参数说明:pos为起始位置(默认为0),n为结束位置(默认为npos)

返回值:子字符串

#include<string>
#include<iostream>
using namespace std;
int main()
{
  string s("12345asdf");
  string a = s.substr(0,5);     //获得字符串s中从第0位开始的长度为5的字符串
  cout << a << endl;
}
//输出结果为:12345
#include <iostream>
#include <string>
#include <vector>
//字符串分割函数
std::vector<std::string> split(std::string str, std::string pattern)
{
    std::string::size_type pos;
    std::vector<std::string> result;
    str += pattern;//扩展字符串以方便操作
    int size = str.size();
    for (int i = 0; i < size; i++)
    {
        pos = str.find(pattern, i);
        if (pos < size)
        {
            std::string s = str.substr(i, pos - i);
            result.push_back(s);
            i = pos + pattern.size() - 1;
        }
    }
    return result;
}
int main()
{
  std::string str;
  std::cout<<"Please input str:"<<std::endl;
  //std::cin>>str;
  getline(std::cin,str);
  std::string pattern;
  std::cout<<"Please input pattern:"<<std::endl;
  //std::cin>>pattern;
  getline(std::cin,pattern);//用于获取含空格的字符串
  std::vector<std::string> result=split(str,pattern);
  std::cout<<"The result:"<<std::endl;
  for(int i=0; i<result.size(); i++)
  {
    std::cout<<result[i]<<std::endl;
  }
 
  std::cin.get();
  std::cin.get();
  return 0;
}

(3) istringstream

stringstream是C++的一个输入输出控制类,作用是将字符串按照空格分割。

头文件 #include <sstream>

#include <sstream>
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    string s = "a/b/c/d";
    istringstream iss(s);
    string buffer;
    while(getline(iss, buffer, '/'))
    {
        cout<<buffer<<endl;
    }
    return 0;
}

可以将字符串分割简单地封装成一个split函数

#include <sstream>
#include <iostream>
#include <vector>
using namespace std;

/**
*分割字符串,输入待分割的字符串s以及分割符sep;
*这里没有对分割可能得到的空串进行处理,可以直接删除空串
*/
vector<string> split(string s, char sep)
{
    istringstream iss(s);
    vector<string> res;
    string buffer;
    while(getline(iss, buffer, sep)){
        res.push_back(buffer);
    }
    return res;
}

int main()
{
    string s = "a/b/c/d";
    vector<string> res = split(s, '/');
    for(int i=0; i<res.size(); i++) cout<<res[i]<<" ";
    cout<<endl;
    return 0;
}

3.二分查找法

参考:(89条消息) 【二分查找】详细图解Charon_cc的博客-CSDN博客二分查找

模板:左闭有闭的写法

重点:就是循环条件和后续的区间赋值问题

总结:在有序的序列中,时间复杂度是logN。

int search(int nums[], int size, int target) //nums是数组,size是数组的大小,target是需要查找的值
{
    int left = 0;
    int right = size - 1;	// 定义了target在左闭右闭的区间内,[left, right]
    while (left <= right) {	//当left == right时,区间[left, right]仍然有效
        int middle = left + ((right - left) / 2);//等同于 (left + right) / 2,防止溢出
        if (nums[middle] > target) {
            right = middle - 1;	//target在左区间,所以[left, middle - 1]
        } else if (nums[middle] < target) {
            left = middle + 1;	//target在右区间,所以[middle + 1, right]
        } else {	//既不在左边,也不在右边,那就是找到答案了
            return middle;
        }
    }
    //没有找到目标值
    return -1;
}
//

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        for (const auto& row: matrix) {
            //lower_bound() 二分查找法
            auto it = lower_bound(row.begin(), row.end(), target);
            if (it != row.end() && *it == target) {
                return true;
            }
        }
        return false;
    }
};

以下是二分查找法的变种题型(check条件)

在排序数组中查找数字 I_(剑指 Offer)

class Solution {
public:
    int search(vector<int>& nums, int target) {
        if(!nums.size())
            return 0;
        int i = 0,j = nums.size() - 1;
        while(i <= j){
            int m = (i + j)/2;
            if(nums[m] <= target)
                i = m + 1;
            else
                j = m - 1;
        }
        int right = i;
        if(j >= 0 && nums[j] != target)
            return 0;
        i = 0;
        j = nums.size() - 1;
        while(i <= j){
            int m = (i + j)/2;
            if(nums[m] < target){
                i = m + 1;
            }else
                j = m - 1;
        }
        int left = j;
        return right - left - 1;
    }
};

0~n-1中缺失的数字_(剑指 Offer)

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int l = 0,r = nums.size() - 1;
        while(l <= r){
            int mid = (l + r) >> 1;
            if(nums[mid] == mid)
                l = mid + 1;
            else
                r = mid - 1;
            
        }
        return nums[r] != r ? r : r + 1;
    }
};
4.计算二位数组的行列数
#include<iostream>
using namespace std;
int main(){
	int a[2][3] = {{1,2,3},{4,5,6}};
	int lines = sizeof(a) / sizeof(a[0][0]);
	int row = sizeof(a) / sizeof(a[0]);       // 行
	int col = lines / row;					// 列
	cout << row << col;
	return 0;
}
5.计算vector二位矩阵的行列数
#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main(){
	//创建4*5二维数组,并将数组元素的值都设为1
	vector<vector<int>> dp(4, vector<int>(5, 1));
	//打印二维数组
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 5; j++)
			cout << dp[i][j] << " ";
		cout << endl;
	}
	cout << endl;

	int m = dp.size();//行数
	int n = dp[0].size();//列数
	cout << "m = " << m << endl;
	cout << "n = " << n << endl;
	return 0;
}
###############################################################################

str.find(i) == str.end() //说明没到
str.find(i) != str.end() //说明找到了
这是标准库里迭代器部分的内容,简单点说,就是用find这个函数,去找str这个序列中的i元素,如果序列中所找的这个元素不存在,就会返回end()。
6.求vector 和 数组的最值问题
1)vector容器
例 vector<int> v;
最大值:int maxValue = *max_element(v.begin(),v.end()); 
最小值:int minValue = *min_element(v.begin(),v.end());

2)普通数组
例 a[]={1,2,3,4,5,6};
最大值:int maxValue = *max_element(a,a+6); 
最小值:int minValue = *min_element(a,a+6);
7.求vector的和
#include<numeric>  //使用accumulate函数要包含这个头文件
 
vector<float> result = {1.2, 2.3, 3.4};
float scoreSum = accumulate(result.begin(), result.end(), 0.0);
8.求最大公约数
int func(int n,int m)
{
    int a,b,c;
    a = n;b = m;
    if(a < b)
        swap(a,b);
    
    c=a % b;
    while(c != 0){
        a=b;
        b=c;
        c=a%b;
    }
    return b;
}
9.int 与 string 相互转化
int max = num;
 //int -> string
 string str = std::to_string(num);
 //string -> int
 int shu =  stoi(str);
10. 链表的头插法和尾插法
// C 语言的写法
#include <stdio.h>
#include <stdlib.h> 
#include <stdbool.h>
#define ElemType int 
typedef struct LNode{
	ElemType Data;
	struct LNode *Next;
}LNode,*LinkList;

//1.链表的创建 (头插法) 
LinkList CreateList_Head(LinkList L)
{
	LinkList s;int x;
	L = (LNode*)malloc(sizeof(LNode));    
	L->Next=NULL;                          
	scanf("%d",&x);                       
	while(x!=9999){                             
		s=(LNode*)malloc(sizeof(LNode));  
		s->Data=x;                           
		s->Next=L->Next;                      
		L->Next=s;
		scanf("%d",&x);
	}
	return L;
}
//2.尾插发 
LinkList CreateList_Tail(LinkList L)
{
	int x;
	L = (LNode*)malloc(sizeof(LNode));
	LNode *s,*r=L;
	scanf("%d",&x);
	while(x!=9999){                             
		s=(LNode*)malloc(sizeof(LNode));     //创建新的结点 
		s->Data=x;                           
		r->Next=s;                      
		r=s;
		scanf("%d",&x);
	}
	r->Next=NULL;
	return L;
 } 


void PrintList(LinkList L)
{
    LinkList p;
    p=L->Next; 
    printf("链表元素如下:\n");
    while(p!=NULL)
    {
        printf("%d ",p->Data);
        p=p->Next;
    }
    printf("\n");
}
int main()
{
	LinkList L;//结构变量L即表示整个链表,也是头指针指向头结点
	printf("尾插法建立单链表,输入值(9999结束)\n"); 
    L=CreateList_Head(L);
    PrintList(L);
    printf("头法建立单链表,输入值(9999结束)\n");
    L=CreateList_Tail(L);
    PrintList(L);
	return 0;
}
Leetcode的写法

        ListNode* temp1 = new ListNode(-1);
        ListNode* temp2 = new ListNode(-1);
        
        //尾插法--建立链表
        ListNode* L = temp1; 
        for(ListNode* temp = head; temp != nullptr; temp = temp->next){
            ListNode* s = new ListNode(temp->val);
            L->next = s;
            L = s;
        }
        //头插法--反转链表
        for(ListNode* temp = head; temp != nullptr; temp = temp->next){
            ListNode* s = new ListNode(temp->val);
            s->next = temp2->next;
            temp2->next = s;
        }
        temp1 = temp1->next;
        temp2 = temp2->next;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值