数据结构(实时更新)(烂尾)

一、线性结构:单前驱,单后继

只有前后关系,没有上下级关系

1.1数组

1.2链表

1.3栈

存储区借助数组或链表

1.3.1数组实现

头文件

#include "../../C/UTILITY.H"
 #include "../../C/UTILITY.CPP"
 typedef double Stack_entry; //类型复用,计算机才能识别Stack_entry,编译为double
 #include "../STACK/STACK.H" 
 #include "../STACK/STACK.CPP"
  #include "COMMANDS.CPP" 

Stack的成员组成

const int maxstack = 10; // small value for testing
class Stack
{ 
public:
	 Stack();//构造stack,所以返回值肯定是stack,所以就不写返回值
 	 bool empty() const;//判空
  	 Error_code pop(); 
     Error_code top(Stack_entry &item) const;//返回栈顶最上元素//只有Error_code返回状态码正常,item才是真正栈顶元素。
     Error_code push(const Stack_entry &item); //
private: 
	 int count;//栈里的有效元素
 	 Stack_entry entry[maxstack]; //存储区
 };

关于const:
const关键字放于函数后面,表示该函数是一个常成员函数,在该函数内不能修改该类的成员变量。
const关键字放于函数前面,表示该函数的返回值为常量,不可以修改。
关于 Error_code
Error_code用于判断是否成功存储
P678头文件utility.h

enum Error_code 
{ 
	success, fail, range_error, underflow, overflow, fatal, not_present, duplicate_error, entry_inserted, entry_found, internal_error 
};

成员函数:
Stack::Stack()

Stack::Stack() /* Pre: None. Post: The stack is initialized to be empty. */ 
{
	 count = 0; 
} 

bool empty() const

bool Stack::empty() const /* Pre: None. Post: If the Stack is empty, true is returned. Otherwise false is returned. */ 
{
	 bool outcome = true; 
	 if (count > 0) outcome = false; 
	 return outcome; 
}

这样写更简洁明了

bool Stack::empty() const /* Pre: None. Post: If the Stack is empty, true is returned. Otherwise false is returned. */ 
{
	 return 0==count; //这样写不容易出错,若写成0=count编译不能通过
}

Error_code Stack::push(const Stack_entry &item)

Error_code Stack::push(const Stack_entry &item) /* Pre: None. Post: If the Stack is not full, item is added to the top of the Stack. If the Stack is full, an Error_code of overflow is returned and the Stack is left unchanged. */ 
{ 
	Error_code outcome = success; 
	if (count >= maxstack) //==本来就够了,不可能大于,但不动脑筋就写>=,写代码有多种选择,逻辑正确就行
		outcome = overflow; //上溢出
	else 
		entry[count++] = item;
    return outcome;
 }

拿到数据item直接通过引用到数据区(用括号传进来就直接传给数据区<不能修改>),函数就是在判断是否还有空间,而Error_code==success这个数据才真正成功存入存储区。

Error_code Stack::pop()

Error_code Stack::pop() /* Pre: None. Post: If the Stack is not empty, the top of the Stack is removed. If the Stack is empty, an Error_code of underflow is returned. */
 {
	  Error_code outcome = success; 
	  if (count == 0)
	     outcome = underflow; 
	  else 
	    --count;
	  return outcome; 
  }

Error_code Stack::top(Stack_entry &item)

Error_code Stack::top(Stack_entry &item) const /* Pre: None. Post: If the Stack is not empty, the top of the Stack is returned in item. If the Stack is empty an Error_code of underflow is returned. */
{ 
	 Error_code outcome = success;
	 if (count == 0) 
		 outcome = underflow; 
	 else 
		 item = entry[count - 1];//item被拷,因为&item,引用,改变的就是存储区的item
	 return outcome;
 } 

1.3.2数组栈的应用

1.3.2.1括号问题
// ==================== BRACKETS ================================ //MAIN.CPP 
#include "../../C/UTILITY.H" 
#include "../../C/UTILITY.CPP" 
typedef char Stack_entry; 
#include "../STACK/STACK.H" 
#include "../STACK/STACK.CPP" 
int main()
 /* Post: The program has notified the user of any bracket mismatch in the standard input file. Uses: The class Stack. */ 
{
  Stack openings;
  char symbol; 
  bool is_matched = true;
  cout << "Bracket checking program.\n" 
   		<< "Enter a line of text to check." << endl; 
  while (is_matched && (symbol = cin.get()) != '\n')
  {
    if (symbol == '{' || symbol == '(' || symbol == '[') 					openings.push(symbol);
	  if (symbol == '}' || symbol == ')' || symbol == ']') 
		 {
		  if (openings.empty()) 
 			{ 
 				cout << "Unmatched closing bracket " << symbol << " detected." << endl; is_matched = false;
 			}
 		  else
 	 		{
 	 			char match; openings.top(match);
 			 	openings.pop();
 	 			is_matched = (symbol == '}' && match == '{') 
 	 			|| (symbol == ')' && match == '(') 
 	 			|| (symbol == ']' && match == '['); 
 	  			if (!is_matched) 
 	   				cout << "Bad match " << match << symbol << endl;
 	   		} 
 	     }
  }
 if (!openings.empty()) 
 	cout << "Unmatched opening bracket(s) detected." << endl; 
}
1.3.2.2计算器

中缀表达式:a+b,(a+b)*(c+d)
后缀表达式:ab+,ab+cd+*

后缀表达式不需要括号 逆波澜式reverse Polish calculator
二元运算符,连续弹出两项,第一个弹出的是第二运算数,第二个弹出的是第一运算数
在这里插入图片描述
计算器对后缀表达式进行处理

int main() /* Post: The program has executed simple arithmetic commands entered by the user. Uses: The class Stack and the functions introduction, instructions, do_command, and get_command. */ 
{ 
	 Stack stored_numbers;
	 introduction(); 
	 instructions(); 
	 while (do_command(get_command(), stored_numbers)); 
 } 
//=================CALCULATOR=================== //COMMANDS.CPP-------------
void introduction() 
{ 
	cout << "Reverse Polish Calculator Program." <<"\n----------------------------------" << endl << endl; 
} 
void instructions() 
{ 
	cout << "User commands are entered to read in and operate on integers." << endl;
	 cout << "The valid commands are as follows:" 
	 << endl << "[Q]uit." 
	 << endl<< "[?] to enter an double number onto a stack." 
	 << endl << "[=] to print the top  double number in the stack."
  	 << endl << "[+] [-] [*] [/] are arithmetic operations."
  	 << endl 
     << "These operations apply to the top pair of stacked  double numbers."<< endl; 
} 
char get_command() //取一个命令,一直输入,直到输入的是合法的
{
    char command;
    bool waiting = true;//上来就认为不合适,要一直输入,直到合法
    cout << "Select command and press <Enter>:"; //选一个命令
    while (waiting)
    { 
    	cin >> command;
    	command = tolower(command); //tolower把当前的字母变成小写字母
    	if (command == '?' || command == '=' || command == '+' || command == '-' || command == '*' || command == '/' || command == 'q' ) //如果合法
    		waiting = false; //终止循环
    	else //如果使用者叛逆,没有输入7个合法命令
    	{ 
    		cout << "Please enter a valid command:" << endl
    		 << "[?]push to stack [=]print top" << endl 
    		 << "[+] [-] [*] [/] are arithmetic operations" << endl 		<< "[Q]uit." << endl;
    	} 
	} 
	return command;
} 
bool do_command(char command, Stack &numbers) /* Pre: The first parameter specifies a valid calculator command. Post: The command specified by the first parameter has been applied to the Stack of numbers given by the second parameter. A result of true is returned unless command == 'q'. Uses: The class Stack. */ 
{
	double p, q;
	switch (command)
	{ 
		case '?':
			cout << "Enter a real number: " << flush; 
			cin >> p; 
			if (numbers.push(p) == overflow) 
			cout << "Warning: Stack full, lost number" << endl; 
		break; 
		case '=': 
			if (numbers.top(p) == underflow) 
				cout << "Stack empty" << endl; 
			else 
				cout << p << endl; 
		break; 
		case '+': 
			if (numbers.top(p) == underflow) 	
				cout << "Stack empty" << endl; 
			else { numbers.pop(); 
				if (numbers.top(q) == underflow) 
				{
					cout << "Stack has just one entry" <<endl; 				
					numbers.push(p); 
				}
				else 
				{ 
					numbers.pop(); 
					if (numbers.push(q + p) == overflow) 
						cout << "Warning: Stack full, lost result" << endl; 
				} 
		} 
		break; // Add options for further user commands. case '-': if (numbers.top(p) == underflow) cout << "Stack empty" << endl; else { numbers.pop(); if (numbers.top(q) == underflow) { cout << "Stack has just one entry" << endl; numbers.push(p); }else { numbers.pop(); if (numbers.push(q - p) == overflow) cout << "Warning: Stack full, lost result" << endl; } } break;
		case '*': 
		if (numbers.top(p) == underflow) cout << "Stack empty" << endl; else { numbers.pop(); if (numbers.top(q) == underflow) { cout << "Stack has just one entry" << endl; numbers.push(p); }else { numbers.pop(); if (numbers.push(q * p) == overflow) cout << "Warning: Stack full, lost result" << endl; } } break;
		case '/': 
			if (numbers.top(p) == underflow) 
				cout << "Stack empty" << endl; 
			else 
				if (p == 0.0) 
				{ 
					cerr << "Division by 0 fails; no action done." << endl; 
					numbers.push(p); 
					// Restore stack to its prior state. 
				}
				else
				{ 
					numbers.pop(); 
					if (numbers.top(q) == underflow) 
					{ 
						cout << "Stack has just one entry" << endl; 					
					}
					else 
					{ 
						numbers.pop(); 
						if (numbers.push(q / p) == overflow) 
							cout << "Warning: Stack full, lost result" << endl; 
							} 
					}
				break; 
				case 'q': 
					cout << "Calculation finished.\n"; 
					return false; 
	} 
	return true;
} 

1.3.3链表栈

1.4队列 queue

在这里插入图片描述
front指向哪,哪里就是头,而不是0号为首。

retrieve(x);取队首元素看一看,从x里看
serve();出队
append(‘a’);a入队

取模运算,对10取余数,可以形成闭环队列

1.4.1实现

//QUEUE.H----------------------------------------------------------------------------------
const int maxqueue = 10; // small value for testing class Queue 
{ 
public: 
	Queue();
 	bool empty() const; //判空,不会改变数据
	Error_code serve();//出队
 	Error_code append(const Queue_entry &item);// 入队
 	Error_code retrieve(Queue_entry &item) const;//看首元素
protected:
	int count; //计数器
 	int front, rear; //首未箭头
  	Queue_entry entry[maxqueue];//Queue_entry类型的数据区
  };

构造函数

  // QUEUE.CPP -----------------------------------------------------------------------------------
Queue::Queue() /* Post: The Queue is initialized to be empty. */
{
    count = 0; //初始化队列里无元素
    rear = maxqueue - 1;//初始化尾下标是满队列-1
    front = 0;
}
bool Queue::empty() const /* Post: Return true if the Queue is empty, otherwise return false. */
{
    return count == 0;
} 

入队append

Error_code Queue::append(const Queue_entry &item) /* Post: item is added to the rear of the Queue. If the Queue is full return an Error_code of overflow and leave the Queue unchanged. */
{
    if (count >= maxqueue) //如果队列满了,就不做了
    	return overflow; 
    count++; 
    rear = ((rear + 1) == maxqueue) ? 0 : (rear + 1);//如果下一个空溢出了,尾下标循环回0,否则正常下标向后推1(实现闭环队列)
    entry[rear] = item; //把item加入队列
    return success;
 } 

出队serve

Error_code Queue::serve() /*Post: The front of the Queue is removed. If the Queue is empty return an Error_code of underflow. */
{ 
   if (count <= 0) 
   	return underflow; 
   count--; 
   front = ((front + 1) == maxqueue) ? 0 : (front + 1);
   return success;
} 

查看首元素

Error_code Queue::retrieve(Queue_entry &item) const /* Post: The front of the Queue retrieved to the output parameter item. If the Queue is empty return an Error_code of underflow. */ 
{ 
if (count <= 0) return underflow; 
item = entry[front]; 
return success; 
}

main

//MAIN.CPP----------------------------------------------------------------------------------
#include "../../C/UTILITY.H" 
#include "../../C/UTILITY.CPP" 
typedef char Queue_entry;
#include "QUEUE.H" 
#include "QUEUE.CPP" 
main() 
{ 
cout << "Enter lines of text and the program duplicates them." << endl; 
cout << "Use Ctrl-Z (EOF) to terminate the program." << endl; 
while (cin.peek() != EOF) 
{
    Queue q; 
    char c; 
    while ((c = cin.get()) != '\n') 
    	q.append(c); 
   		while (!q.empty())
   		{ 
   			 q.retrieve(c); 
   			 cout << c; 
   			 q.serve();
   		} 
   		cout << endl;
   } 
}

扩充功能的队列类

class Extended_queue: public Queue 
{ 
public: 
	bool full() const; 
	int size() const; 
	void clear();
	Error_code serve_and_retrieve(Queue_entry &item);
}; 
//EXTQUEUE.CPP----------------------------------------------------------------------------------
bool Extended_queue::full() const /* Post: Return true if the Extended_queue is full; return false otherwise. */ 
{ 
	return count == maxqueue;
} 
void Extended_queue::clear() /* Post: All entries in the Extended_queue have been deleted; the Extended_queue is empty. */ 
{ 
	count = 0; 
	front = 0; 
	rear = maxqueue - 1; 
} 
int Extended_queue::size() const /* Post: Return the number of entries in the Extended_queue. */
{ 
	return count;
} 
Error_code Extended_queue::serve_and_retrieve(Queue_entry &item) /* Post: Return underflow if the Extended_queue is empty. Otherwise remove and copy the item at the front of the Extended_queue to item. */ 
{ 
	if (count == 0) 
		return underflow; 
	else 
	{ 
		count--; 
		item = entry[front]; 
		front = ((front + 1) == maxqueue) ? 0 : (front + 1); 
	} 
	return success; 
} 

1.4.2 应用

1.4.2.1机场模拟程序

两个类:飞机Plane 跑道Runway
两个队列:一个跑道有等待着陆的飞机队列Landing queue和等待起飞的飞机队列,但着陆的优先级高。
每个队列元素为Plane

enum Plane_status {null, arriving, departing}; 
class Plane 
{ 
public: 
	Plane(); 
	Plane(int flt, int time, Plane_status status); //p104
	void refuse() const; void land(int time) const; 
	void fly(int time) const; 
	int started() const; 
private: 
	int flt_num; //几号飞机
	int clock_start;
	Plane_status state; 
 }; 
//PLANE.CPP-----------------------------------------------------------------------------------
Plane::Plane(int flt, int time, Plane_status status) /* Post: The Plane data members flt_num, clock_start, and state are set to the values of the parameters flt, time and status, respectively. */ 
{ 
	flt_num = flt; 
	clock_start = time; 
	state = status; 
	cout << "Plane number " << flt << " ready to "; if (status == arriving) cout << "land." << endl; else cout << "take off." << endl; 
} 
Plane::Plane() /* Post: The Plane data members flt_num, clock_start, state are set to illegal default values. */ 
{ 
	flt_num = -1; 
	clock_start = -1; 
	state = null; 
} 
void Plane::refuse() const /* Post: Processes a Plane wanting to use Runway, when the Queue is full. */ 
{ 
	cout << "Plane number " << flt_num; 
if (state == arriving) 
	cout << " directed to another airport" << endl; 
else 
	cout << " told to try to takeoff again later" << endl; 
} 
void Plane::land(int time) const /* Post: Processes a Plane that is landing at the specified time. */ 
{ 
	int wait = time - clock_start; 
	cout << time << ": Plane number " << flt_num << " landed after " << wait << " time unit" << ((wait == 1) ? "" : "s") << " in the landing queue." << endl; 
}
void Plane::fly(int time) const /* Post: Process a Plane that is taking off at the specified time. */ 
{ 
	int wait = time - clock_start; 
	cout << time << ": Plane number " << flt_num << " took off after " << wait << " time unit" << ((wait == 1) ? "" : "s") << " in the takeoff queue." << endl; 
} 
int Plane::started() const /* Post: Return the time that the Plane entered the airport system. */ 
{ 
	return clock_start; 
} 
enum Runway_activity {idle, land, take_off}; 
class Runway 
{ 
public: 
	Runway(int limit); 
	Error_code can_land(const Plane &current); 
	Error_code can_depart(const Plane &current); 
	Runway_activity activity(int time, Plane &moving); //
	void shut_down(int time) const; //统计数据
private: 
	Extended_queue landing; 
	Extended_queue takeoff; 
	int queue_limit; 
	int num_land_requests; // number of planes asking to land 
	int num_takeoff_requests; // number of planes asking to take off 
	int num_landings; // number of planes that have landed 
	int num_takeoffs; // number of planes that have taken off 
	int num_land_accepted; // number of planes queued to land 
	int num_takeoff_accepted; // number of planes queued to take off 
	int num_land_refused; // number of landing planes refused 
	int num_takeoff_refused; // number of departing planes refused 
	int land_wait; // total time of planes waiting to land 
	int takeoff_wait; // total time of planes waiting to take off 
	int idle_time; // total time runway is idle };
//RUNWAY.CPP----------------------------------------------------------------------------------
Runway::Runway(int limit) /* Post: The Runway data members are initialized to record no prior Runway use and to record the limit on queue sizes. */ 
{ 
	queue_limit = limit; 
	num_land_requests = num_takeoff_requests = 0; 
	num_landings = num_takeoffs = 0; 
	num_land_refused = num_takeoff_refused = 0; 
	num_land_accepted = num_takeoff_accepted = 0; 
	land_wait = takeoff_wait = idle_time = 0; 
} 
Error_code Runway::can_land(const Plane &current) /* Post: If possible, the Plane current is added to the landing Queue; otherwise, an Error_code of overflow is returned. The Runway statistics are updated. Uses: class Extended_queue. */ 
{ 
	Error_code result; 
	if (landing.size() < queue_limit) 
		result = landing.append(current); 
	else result = fail; 
		num_land_requests++; 
	if (result != success) 
		num_land_refused++; 
	else 
		num_land_accepted++; 
	return result; 
} 
Error_code Runway::can_depart(const Plane &current) /* Post: If possible, the Plane current is added to the takeoff Queue; otherwise, an Error_code of overflow is returned. The Runway statistics are updated. Uses: class Extended_queue. */ 
{ 
	Error_code result; 
	if (takeoff.size() < queue_limit) 
		result = takeoff.append(current); 
	else result = fail; 
		num_takeoff_requests++; 
	if (result != success) 
		num_takeoff_refused++; 
	else num_takeoff_accepted++; 
	return result; 
}
Runway_activity Runway::activity(int time, Plane &moving) /* Post: If the landing Queue has entries, its front Plane is copied to the parameter moving and a result land is returned. Otherwise, if the takeoff Queue has entries, its front Plane is copied to the parameter moving and a result takeoff is returned. Otherwise, idle is returned. Runway statistics are updated. Uses: class Extended_queue. */ 
{ 
Runway_activity in_progress; 
if (!landing.empty()) //有着陆的飞机
{ 
	landing.retrieve(moving); //取走
	land_wait += time - moving.started(); //等待的时间
	num_landings++; //着陆了
	in_progress = land; landing.serve(); //
} 
else if (!takeoff.empty()) //没有着陆的飞机,有起飞的飞机
{ 
	takeoff.retrieve(moving); //起飞的取走
	takeoff_wait += time - moving.started(); //起飞等待时间
	num_takeoffs++; 
	in_progress = take_off; 
	takeoff.serve(); 
} 
else //没有着陆的飞机,没有起飞的飞机
{ 
	idle_time++; 
	in_progress = idle; 
} 
return in_progress; 
} 
void Runway::shut_down(int time) const /* Post: Runway usage statistics are summarized and printed. */ 
{ 
	cout << "Simulation has concluded after " << time << " time units." << endl 
		<< "Total number of planes processed " << (num_land_requests + num_takeoff_requests) << endl 
		<< "Total number of planes asking to land " << num_land_requests << endl 
		<< "Total number of planes asking to take off " << num_takeoff_requests << endl 
		<< "Total number of planes accepted for landing " << num_land_accepted << endl 
		<< "Total number of planes accepted for takeoff " << num_takeoff_accepted << endl 
		<< "Total number of planes refused for landing " << num_land_refused << endl 
		<< "Total number of planes refused for takeoff " << num_takeoff_refused << endl 
		<< "Total number of planes that landed " << num_landings << endl 
		<< "Total number of planes that took off " << num_takeoffs << endl 
		<< "Total number of planes left in landing queue " << landing.size() << endl 
		<< "Total number of planes left in takeoff queue " << takeoff.size() << endl; 
	cout << "Percentage of time runway idle " << 100.0 * (( float ) idle_time) / (( float ) time) << "%" << endl; 
	cout << "Average wait in landing queue " << (( float ) land_wait) / (( float ) num_landings) << " time units"; 
	cout << endl << "Average wait in takeoff queue " << (( float ) takeoff_wait) / (( float ) num_takeoffs) << " time units" << endl; 
	cout << "Average observed rate of planes wanting to land " << (( float ) num_land_requests) / (( float ) time) << " per time unit" << endl; 
	cout << "Average observed rate of planes wanting to take off " << (( float ) num_takeoff_requests) / (( float ) time) << " per time unit" << endl; 
} 
#include "../../C/UTILITY.H" 
#include "../../C/UTILITY.CPP" 
#include "PLANE.H" 
#include "PLANE.CPP" 
typedef Plane Queue_entry; 
#include "../QUEUE/QUEUE.H" 
#include "../QUEUE/QUEUE.CPP" 
#include "../EXTQUEUE/EXTQUEUE.H"
#include "../EXTQUEUE/EXTQUEUE.CPP" 
#include "RUNWAY.H"
#include "RUNWAY.CPP" 
#include "../../B/RANDOM.H" 
#include "../../B/RANDOM.CPP" 
void initialize(int &end_time, int &queue_limit, double &arrival_rate, double &departure_rate) /* Pre: The user specifies the number of time units in the simulation, the maximal queue sizes permitted, and the expected arrival and departure rates for the airport. Post:Theprogramprintsinstructionsandinitializestheparametersend_time,queue_limit,arrival_rate, and departure_rate to the specified values. Uses: utility function user_says_yes */ { cerr << "This program simulates an airport with only one runway." << endl << "One plane can land or depart in each unit of time." << endl; 
cerr << "Up to what number of planes can be waiting to land " << "or take off at any time? " << flush; 
cin >> queue_limit; cerr << "How many units of time will the simulation run?" << flush; 
cin >> end_time; 
bool acceptable; 
do 
{ 
cerr << "Expected number of arrivals per unit time?" << flush; cin >> arrival_rate; 
cerr << "Expected number of departures per unit time?" << flush; cin >> departure_rate; 
if (arrival_rate < 0.0 || departure_rate < 0.0) cerr << "These rates must be nonnegative." << endl; 
else acceptable = true; 
if (acceptable && arrival_rate + departure_rate > 1.0) cerr << "Safety Warning: This airport will become saturated. " << endl; } 
while (!acceptable); 
} void run_idle(int time) /* Post: The specified time is printed with a message that the runway is idle. */ { cout << time << ": Runway is idle." << endl; } int main() // Airport simulation program /* Pre: The user must supply the number of time intervals the simulation is to run, the expected number ofplanesarriving,theexpectednumberofplanesdepartingpertimeinterval,andthemaximumallowed size for runway queues. Post: The program performs a random simulation of the airport, showing the status of the runway at each time interval, and prints out a summary of airport operation at the conclusion. Uses: Classes Runway, Plane, Random and functions run_idle, initialize. */ { int end_time; // time to run simulation int queue_limit; // size of Runway queues int flight_number = 0; double arrival_rate, departure_rate; initialize(end_time, queue_limit, arrival_rate, departure_rate); Random variable; Runway small_airport(queue_limit); for (int current_time = 0; current_time < end_time; current_time++) { // loop over time intervals int number_arrivals = variable.poisson(arrival_rate); // current arrival requests for (int i = 0; i < number_arrivals; i++) { Plane current_plane(flight_number++, current_time, arriving); if (small_airport.can_land(current_plane) != success) current_plane.refuse(); } int number_departures= variable.poisson(departure_rate); // current departure requests for (int j = 0; j < number_departures; j++) { Plane current_plane(flight_number++, current_time, departing); if (small_airport.can_depart(current_plane) != success) current_plane.refuse(); } Plane moving_plane; switch (small_airport.activity(current_time, moving_plane)) { // Let at most one Plane onto the Runway at current_time. case land: moving_plane.land(current_time); break; case take_off: moving_plane.fly(current_time); break; case idle: run_idle(current_time); } } small_airport.shut_down(end_time); }

二、树形结构:单前驱,多后继

三、网状结构:多前驱,多后继

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值