java——傻瓜电梯

学习目标:

按照文档实现傻瓜电梯,具体要求入下:
1、每组2-4人
2、完成公测用例。如果未完成公测用例需要说明完成公测用例第几到第几个,未完成那几个。
3、注意增加合理代码注释。
4、注意变量,函数和类名的命名规范。命名原则:能一眼识别出来,例如 年龄 iAge 体现变量类型和逻辑意义。
5、注意电梯临界时间,如果计算时间和公测用例和文档不一致,如果能给出合理解释需提供相关文档说明。
6、注意合理的封装,例如某些公共功能如何封装更合理。

要求:

一:要求;

OO 第二次作业要求  
                           2018
1.	作业目标 
通过设计一个简单的单部电梯运行控制系统,要求设计者以面向对象程序的 设计方式来实现电梯控制系统的具体功能。
2. 作业内容和成果物 
2.1 业务背景 
1) 电梯定义 电梯是服务于规定楼层的固定式升降设备。垂直升降电梯具有一个轿厢,运 行在至少两列垂直的或倾斜角小于 15°的刚性导轨之间。台阶式自动扶梯和滚 梯不在本次作业考虑范围之内。 
2) 电梯的简单使用方法(不考虑紧急情况和复杂情况): 载人电梯都是微机控制的智能化、自动化设备,不需要专门的人员来操作驾 驶,普通乘客只要按下列程序乘坐和操作电梯即可。 
i) 在乘梯楼层电梯入口处,根据自己上行或下行的需要,按向上或向下的 箭头按钮,只要按钮上的灯亮,就说明你的呼叫已被记录,只要等待电 梯到来即可。
ii) 电梯到达目标楼层停下开门后,先让轿厢内人员走出电梯,然后呼梯者 再进入电梯轿厢。进入轿厢后,根据你需要到达的楼层,按下轿厢内操 纵盘上相应的数字按钮。同样,只要该按钮灯亮,则说明你的目标楼层 已被记录;此时不用进行其他任何操作(在到达目标楼层之前,反复按 该目标楼层的按钮为无效操作),一旦电梯门关闭之后,电梯就会开始 运动,只要等电梯到达你的目标层停靠开门即可。
iii) 电梯行驶到你的目标层后会自动开门,此时按顺序走出电梯即结束 了一次乘梯过程。
 2 / 8 
2.2 作业电梯系统基本描述 
1) 本作业的电梯为一个运行在 10 层楼的电梯,电梯可在每层经停。楼层计数 采用中国式楼层计数,即 1 层显示为 12 层为 2,依次类推,直至顶层显示 为 102) 每个楼层都有一组电梯运行请求按钮(下面简称为楼层按钮),即上行请求 按钮和下行请求按钮。如果乘客按上行请求按钮时,则表示想搭乘电梯去往 上面的楼层;反之,则表示想搭乘电梯去往下面的楼层。规定最底层(1 层) 只有上行请求按钮,最顶层(10 层)只有下行请求按钮,中间楼层同时有上 行和下行两个方向请求按钮。
 3) 一个电梯箱体(剩余文档简称电梯)内有对应每个楼层的目的地请求按钮(下 面简称目标楼层),一般显示相应楼层的层数。 
2.3 电梯基本运行规则
 1) 程序运行开始或重置时设置电梯停靠在一层; 
2) 几个名词解释: a) 电梯运行状态:从电梯启动时刻(此时速度>0,到电梯运动停止时(此 时速度刚刚为 0)的运行状态。(启动时刻,运行停止时刻],期间运行 速度始终大于 0。 b) 电梯开关门状态:电梯静止时,从门打开时刻(门开始动作),到门完 全关闭时刻(门刚刚停止动作)时的状态。(门打开时刻,门关闭时刻] c) 电梯停留状态:电梯停在某层,且门长时间处于关闭状态。(门关闭时 刻,门准备打开时刻或电梯准备启动时刻]
 3) 一个楼层按钮同一时刻只能发出一个上行或下行请求。电梯未到本楼层的时 候,某个请求按钮变亮后,再按不会产生实际效果,但是发出上行请求后可 以再发出下行请求,反之亦可,这视为两个不同的请求,执行完一个后另一 个仍需执行。在电梯到达某楼层处于开关门状态时,该楼层的多个同向请求 只认为是一个请求。当电梯关门动作完成后(含门完全静止的那一刻),可 以再产生新的上下行请求; 
4) 电梯内的一个目标楼层按钮只能发出对应目标楼层的请求,一旦发出某个目 标楼层请求后,在电梯到达该楼层并完成关门动作前(包括关门完毕时刻), 3 / 8 目标楼层与该按钮楼层相同的多个电梯内请求被认为是一个请求。当电梯关 门结束后,可以再发出任意目标楼层请求。 
5) 所有请求按照请求发出的时间顺序被电梯系统管理和调度,按照时间上先来 先服务的策略(First Arrived First Served,FAFS)进行调度。 
6) 如果电梯同时收到了电梯内请求和楼层请求时,则按照输入时的请求排列顺 序执行。 7) 本次作业的电梯系统采用傻瓜式调度策略:控制系统不断扫描请求队列,按 照 FAFS 策略取出待响应请求,只有当该请求被执行完毕之后,才会尝试调 度下一个请求。请注意此处不要按照常见的电梯运行调度策略进行优化设计, 不要合并“顺路”的请求。如从 2 层去 8 层期间,未到 6 层时有 6 层的上行 请求,应先处理完 2 层到 8 层的请求,再处理 6 层的请求;或者 2 层到 8 层 时,中间又发出了去 6 层的请求,同样先执行完到 8 层的动作,再处理去 6 层的请求。 
3. 作业内容和成果物 
3.1 作业内容 
实现一个符合 2.2 节和 2.3 节所描述的电梯运行调度 java 程序。 
3.2 提交内容 
1)java 语言程序(java 程序文件); 
2)程序说明文档(Readme),内容包括: 
a) 电梯调度策略和程序功能说明; 
b) 程序运行所需环境和运行指令规范; 
c) 程序的输入说明,包括标准输入格式、输入限制和遇见输入错误时的 响应信息; 
d) 程序计算结果的输出规格,以及可预见的运行错误响应信息; 
3)程序中若干类的说明文档(Readme,word 文件),详见 4.4 节。 
4. 作业要求和限制 
4.1 输入规范 用户输入为按照请求产生时间排序的请求序列(注意:可以输入时间相同的 两个请求,排在前面请求被优先执行),序列通过字符串表示; 
4 / 8 
请求分为两类:一类是楼层请求,一类是电梯内请求。 
楼层请求格式为:(FR, m, UP/DOWN, T),其中 FR 为楼层请求标识,m 为发 出请求的楼层号,UP 为向上请求,DOWN 为向下请求,T 为发出时刻。(注释:相 当于请求者在楼道里的某楼层按“上行”或“下行”键) 电梯内请求格式为:(ER, n, T),其中 ER 为电梯内请求标识,n 为请求前往 的目标楼层号,T 为发出时刻。(注释:相当于人在电梯里按一个目标楼层号) 所有的逗号应采用 ASCII 字符集中的逗号“,”,而不是中文字符逗号“,”。 请求之间必须通过换行进行分隔,两条请求之间不允许有空行。一条请求的内部 元素之间可以有空格,要求程序能够自动过滤。  运行规则: T 为请求产生的相对时刻,第一个请求的 T 值必须设置为 0,否则视为一个 crash 错误!设电梯运行一个楼层距离的时间消耗为 0.5s;达到楼层后一次开关 门动作时间消耗为 1.0s。 合法的请求产生时刻为非负整数(要求最大为 4 字节的非负整数,格式不得 为-0),n,m 为 1~10 之间(包含)的正整数。 不正确的标识符,不正确的方向,不正确的数字范围,多余的其他非允许字 符,均认定为不合法输入,即无效输入。 特别地,对于 FR 标识符,1 楼的 DOWN 和 10 楼的 UP 也认为是无效输入。 在一行内只能输入一条请求,一行内输入多条请求将导致 OJ 无法识别!输 入全部请求后,必须再键入 RUN 表示输入结束,回车后程序开始执行调度。 本程序中的 T 和 t 均为模拟值,即不要按照 T 和 t 的值作为真实时间来控制 运行输出。 参考输入样例(例 1): (FR,3,DOWN,0)
 (FR,1,UP,1) 
(ER,1,2) 
(ER,6,4) 
RUN

本次作业要求一次性输入所有请求,然后执行程序进行电梯调度并输出结果。 标准输入的请求是按照时间排序的,如果遇到一个乱序的请求,即请求产生时间 小于前面一个请求产生时间,则该请求直接被丢掉,继续处理下一个请求。 要求程序能够忽略相同的请求,包括产生时刻相同的相同请求和产生时刻不 同但是实质上相同的请求。详情见 2.3.32.3.4 中的规定。 
例 2(FR,3,DOWN,0) (FR,3,DOWN,1) RUN 根据前面的运行规则,例 2 中的第二条请求发出时第一条请求还没有执行结 束,相当于楼梯按钮仍处于“按下状态”(即电梯尚未到达 3 层,而请求者多次 按了“下行按钮”),所以第二条请求与第一条请求实质上相同。 
例 3(FR,3,DOWN,0) (FR,3,DOWN,1000) RUN 第二条请求执行时,按照运行规则此时电梯已到 3 层,该请求相当于是同层 请求(即电梯停在本层),应执行一次开关门动作。对于电梯内请求的类似情况 同理。 本次作业不要求楼层请求和电梯请求的顺序符合真实情况(所谓真实情况, 即实际情况中电梯中如果没有乘客,不会产生电梯内请求,但本次作业做简化考 虑,任何顺序的楼层和电梯内请求都可被接受) 本次作业不允许使用文件作为输入。 除黑体和红色字表明的强制规定外,对于更多的细节的输入规范,如与文档 冲突,请在 readme 说明文档(PDF 文件)中说明,若没有说明且与文档的冲突, 测试者有理由质疑。 
4.2 输入方式 本程序运行要求为控制台或命令行输入,具体输入方式由程序设计者决定, 但是要求在说明文档中加以明确说明。 
6 / 8 
4.3 输出规范 
程序的输出为按照时间排序的电梯运行状态描述,包括以下内容:电梯停靠 的楼层、停靠前的运动方向及停靠时刻(即电梯刚到达目标楼层由运动转为静止 状态,尚未执行开关门的时刻): 格式为:(n,UP/DOWN,t) 注意:一行只有一个输出结果,若一行内有多个输出结果,则 OJ 无法识别! 其中 n 为楼层号,UP/DOWN 为电梯运行方向(只显示 UP 或 DOWN 之一); t 为相对于第一个请求发生的时间。对于 t 的规格有如下要求:t 是保留小数点 后一位有效位的浮点数,如果 t=3,则要求输出为 3.0;如果 t=0,则要求输出 0.0。不允许出现-0.0 的格式。否则会导致 OJ 误判!。 有同层请求时(即电梯停在某层,此时有目标为该层的请求),则输出为: (n,STILL,t),此处 t 应考虑电梯执行一次开关门动作的时间。 输出必须使用 system.out 标准输出,否则会导致 OJ 误判! 例: 输入为(ER,1,0) 时,应输出(1,STILL,1.0)。解释:电梯停在 1 层,此时在电梯 内发出去 1 层的请求,则输出开关门一次后的时刻。 输入为(ER,3,0) (ER,3,5) 时,应输出: (3,UP,1.0) (3,STILL,6.0) 输出格式要求采用 UTF-8 标准。 对于本程序不能识别的输入内容,必须按照以下规格进行输出,否则按照错 误结果扣分! ERROR #所对应的错误输入内容 相关的输出规范要在说明文档(README)中加以说明。 其他未规定的地方可由编程者自行决定。但是需要在 readme 中说明 
4.4 设计要求 本次作业不能使用 lamda 表达式编程! 
7 / 8 
必须要实现电梯、楼层、请求队列、调度器、请求这五个类,且类中不允许 出现 Public 属性。其中楼层类可能相对简单一些,不做具体要求,但是其他四 个类的具体实现必须单独编写说明文件,内容包括类属性和方法的简要说明。 电梯类 调度器类 请求队列类 请求类 发出指令 访问请求 管理请求 发出请求 楼层类 发出请求 command schedule 几个类之间的协作关系参考图 
5. 其它说明事项 
5.1 设计建议 
(1)从输入读取请求 
(2)构造请求对象
 (3)加入到队列中 
(4)启动调度 
(5)记录电梯对象对请求的响应 
5.2 错误处理 处理原则: 
1) 如果发现输入请求序列不满足时间排序要求,则输出无效输入提示(输出 格式为#开头的提示内容),并忽略不满足要求的请求,继续处理下一个 输入请求。 
2) 遇到无效请求(包括格式或内容不符合要求的),需要给出无效输入提示 后,继续处理下一个输入请求直至结束。 
3) 格式有误或数据无效(如楼层超过 10)的请求将被直接从输入请求序列中 去掉,并给出无效输入提示,但不影响继续对其他有效请求的调度处理。 
8 / 8 
4) 任何情况下,程序都不应 crash,要正常结束(exitcode=0)。 
5.3 Tips 如何设计 3 个对象:电梯箱体、楼层、调度器,它们的定义是什么,有什么 (属性);它们能做什么,在什么情况下做(方法)。同理,分析另外 2 个内部 管理类。 
6. 其他规定 
1) 文档中粗体字体部分为强制要求。 
2) 无效作业,以下四种情况视为无效作业。 
(1)程序不能编译和运行; 
(2)未使用 Java 语言; 
(3)所编制的程序不是本次作业的内容。 
(4)无法通过任何一个可以输出正常结果的公共测试案例;

二:代码目录:
在这里插入图片描述
三:代码实现及注释:
(1)Main.java:

import java.util.LinkedList;

public class Main {
	public static void main(String[] args) {      //程序入口
        Input input = new Input();
        LinkedList<String> list = input.getList();    //new一个Input对象,在getlist()方法中输入命令command,放到list中
        RequestsQueue requestsqueue = new RequestsQueue();  //new一个存储着用户名令的电梯请求队列对象
        while(true) {
        	if(list.isEmpty()==true) list = input.getList();   //得到一个用户输入的有效命令
        
        	String[] command = input.inputchange(list.poll());    //从list中取出一个命令,并在inputchange()方法中把它简化一下
        	
   
        	Elevator elevator = new Elevator();   //new一个电梯对象
        	if(command[0].equals("FR")) {    //如果是对于在电梯外请求的用户的服务
        		System.out.println("***");    
        		elevator.setmode(command[0]);  
        		elevator.setaimfloor(Integer.valueOf(command[1]));
        		elevator.setdirection(command[2]);
        		elevator.setsendtime(Double.valueOf(command[3]));   //把用户输入的命令中得出4个信息,并把相应的值存放到一个电梯对象里
        		requestsqueue.add(elevator);  //把存有用户请求命令的电梯放到电梯请求队列里,等待服务
        	}
        	else if(command[0].equals("ER")) {      //如果三对于在电梯内请求的用户的服务
        		elevator.setmode(command[0]);
        		elevator.setaimfloor(Integer.valueOf(command[1]));
        		elevator.setsendtime(Double.valueOf(command[2]));    //把用户输入的3个信息,并把相应的值存放到一个电题对象里
        		requestsqueue.add(elevator); //把存有用户请求命令的电梯放到电梯请求队列里,等待服务
        	}
        	else System.out.println("ERROR");     //如果吉布森电梯外请求,也不是电梯内请求,那就是不合法的请求,直接输出错误即可
            Solve.error();    //开始让Solve对象做解决操作,即根据相应的命令数据信息,得到运行输出结果
        }
        
	}
}

(2)Elevator.java:


public class Elevator {
   private String mode;   //电梯模式属性 ,ER,FR
   private String direction;  //电梯状态属性,up,DOWN,STILL
   private Double sendtime;  //用户发起请求时间
   private Double endtime=0.0;  //代你提结束云兄时间
   private int nowfloor=1;  //电梯当前所在的楼层,初始化为1
   private int aimfloor;    //电梯所要到的目标楼层
   public void setmode(String mode) {  //设置模式
	   this.mode = mode;
   }
   public void setdirection(String direction) { //设置状态
	   this.direction = direction;
   }
   public void setsendtime(double sendtime) {  //设置发起请求时间
	   this.sendtime = sendtime;
   }
   public void setendtime(double endtime) { //设置电梯结束运行时间
	   this.endtime = endtime;
   }
   public void setnowfloor(int nowfloor) {  //设置电题当前所在楼层
	   this.nowfloor = nowfloor;
   }
   public void setaimfloor(int aimfloor) { //设置电题所要到达的目标楼层
	   this.aimfloor = aimfloor;
   }
   
   //相面六个方法分别为得到电题相应的6个属性值的方法
   public String getmode() {  
	   return this.mode;
   }
   public String getdirection() { 
	   return this.direction;
   }
   public Double getsendtime() {  
	   return this.sendtime;
   }
   public Double getendtime() {
	   return this.endtime;
   }
   public  int getnowfloor() {
	   return this.nowfloor;
   }
   public int getaimfloor() {
	   return this.aimfloor;
   }
}

(3)Floor.java:


public class Floor {
  private int maxFloor=10;  //电梯最高楼层数殉国,初始化为10
  private int minFloor=1;   //电梯最低楼层数殉国,初始化为1
  private void setmaxFloor(int maxFloor) {    //设置最高楼层属性方法
	  this.maxFloor = maxFloor;
  }
  private void setminFloor(int minFloor) {  //设置楼层最低属性方法
	  this.minFloor = minFloor;
  }
  private int getmaxFloor() { //得到最高楼层数
	  return this.maxFloor;
  }
  private int getminFloor() {  //得到最低楼层数
	  return this.minFloor;
  }
}

(4)Input.java:

import java.util.LinkedList;
import java.util.Scanner;

import javax.swing.text.html.HTMLDocument.Iterator;

public class Input {   //该类的功能三让哟玫瑰湖输入命令和简化用户输入的命令
	String[] inputchange(String s) {     //命令简化
		
		s = s.replaceAll(" ", "");    //去掉多余的空格
       
		s = s.replaceAll("\\(|\\)", ""); //去括号
		String[] s1 = s.split(",");  //用都好将肌肤穿进行切割成String数组
		
		return s1;  //把结果返回
	}
	public LinkedList<String> getList(){    //让当前用户输入命令
		Scanner sc = new Scanner(System.in);
		LinkedList<String> list = new LinkedList();
		while(true) {
			String Command=sc.next();
			if(Command.equals("RUN")) {  //RUN输入结束的标志,breakjike1
				break;
			}else {
				list.add(Command); //把该用户居输入的所有,imhling1寸放到一个链表里
			}
		}
		
		return list;		//返回该用户输入的所有命令
	}
	
}

(5)RequestsQueue.java:

import java.util.LinkedList;
import java.util.Queue;

public class RequestsQueue {
	private static Queue<Elevator> queue = new LinkedList<Elevator>();  //存放电梯请求队列,里面的元素三存放了用户命令信息的电梯
	public void add(Elevator elevator) {  //往队列里添加电梯元素
		queue.offer(elevator);
	}
	public Elevator peek() {  //查找元素
		return queue.peek();
	}
	public Elevator poll() { //取出一个元素
		return queue.poll();
	}
}

(6)Solve.java:


public class Solve {  //该类主要实现解决得出最后运行结果的功能呢个
	//该方法主要三针对FR请求的相关计算和判断
	public static String FRSolve(String direction, Integer aimfloor, double sendtime,Integer nowfloor,double endtime) {
		Elevator elevator = new Elevator();  //new一个电梯对象
		if ((aimfloor == 1 && direction.equals("DOWN"))) {  //用户当前在1楼,但请求三项下,不合理
			return "ERROR1";
		} else if ((aimfloor == 10 && direction.equals("UP"))) { //用户当前在10楼,但请求三项上,不合理
			return "ERROR2";
		} else if (endtime > sendtime) {  //拥护发出请求的时间电梯还在为上一个拥护据服务,没办法来服务放弃请求的用户,不合理
			System.out.println(endtime + " " + sendtime);
			return "ERROR3"; 
		} else {  //以下三合里的情况,有3种
			if (aimfloor == nowfloor) {  //目标楼层等于当前所在楼层,电梯相当于不懂,STILL
				sendtime += 1f;   //电梯结束运行时间要加上1,即电梯开关门时间
				//更新电梯的相应属性值
				endtime = sendtime;  
				elevator.setendtime(endtime);
				elevator.setnowfloor(nowfloor);
				return "STILL";
			}
			sendtime += Math.abs(aimfloor - nowfloor) * 0.5;  //不精致的护士用电梯速度*楼层茶树,得到电梯为该用户服务所需要花费的时间按
			//更新电梯结束运行时间按
			endtime = sendtime;  
			if (nowfloor < aimfloor) {   //电梯项上走了的情况,即UP
				//做更新
				nowfloor = aimfloor;
				elevator.setnowfloor(nowfloor);
				elevator.setendtime(endtime);
				return "UP"; 
			} else {     //电梯项下走了的情况,即DOWN 
				nowfloor = aimfloor;
				elevator.setnowfloor(nowfloor);
				elevator.setendtime(endtime);
				return "DOWN";
			}
		}
	}
	
	//该方法主要三针对ER请求的相关计算和判断
	public static String ERSolve(Integer aimfloor, double sendtime) {
		Elevator elevator = new Elevator();
		double endtime = elevator.getendtime();
		Integer nowfloor = elevator.getnowfloor();
		if (sendtime > sendtime) {     //电梯正忙,无法服务
			return "ERROR3";
		} else if (aimfloor < 0 || aimfloor > 10) {  //楼层请求不再合里范围内
			return "ERROR4";
		}
		if (nowfloor == aimfloor) {    //电梯相当于不动,即STILL
			//做更新
			sendtime += 1f;
			endtime = sendtime;
			elevator.setnowfloor(nowfloor);
			elevator.setendtime(endtime);
			return "STILL";
		} else {
			sendtime += Math.abs(aimfloor - nowfloor) * 0.5;//计算花费时间爱女
			//跟新结束运行时间
			endtime = sendtime;
			if (nowfloor > aimfloor) {  //向下走了的情况,即DOWN
				//做更新
				nowfloor = aimfloor;
				elevator.setnowfloor(nowfloor);
				elevator.setendtime(endtime);
				return "DOWN";
			} else {  //向上走了的情况,即UP
				//做更新
				nowfloor = aimfloor;
				elevator.setnowfloor(nowfloor);
				elevator.setendtime(endtime);
				return "UP";
			}
		}
	}
	//该方法三对最终运行结果的输出
	public static void error() {
		RequestsQueue requestqueue = new RequestsQueue();
		while (true) {
			String sDirection;
			if (requestqueue.peek() == null) {
				break;
			} 
			else if (requestqueue.peek().getmode().equals("FR")) {  //FR模式的请求
//				System.out.println(requestQueue.peek().getNowFloor());
				Elevator elevator = requestqueue.poll();//从电梯请求队列里取出一个用户的命令
				sDirection = Solve.FRSolve(elevator.getdirection(), elevator.getaimfloor(),
						elevator.getsendtime(),elevator.getnowfloor(),elevator.getendtime()); //把电题里存放的命令信息作为参数出给FRSolve方法里进行结算和判断
				if (sDirection.equals("ERROR1")) { //不合理的请求或无法服务的
					System.out.println("ERROR");
					System.out.println("#1楼不能下。");
				} else if (sDirection.equals("ERROR2")) {
					System.out.println("ERROR");
					System.out.println("#顶楼不能上。");
				} else if (sDirection.equals("ERROR3")) {
					System.out.println("ERROR");
					System.out.println("#命令发送时间有误。");
				} else { //可以服务的情况
					System.out.println(  //把计算得到的结果进行输出
							"(" + elevator.getnowfloor() + "," + sDirection + "," + elevator.getendtime() + ")");
				}
			} 
			else {  //ER模式的请求
				Elevator elevator = requestqueue.poll();  //求出一个用户命令
				sDirection = Solve.ERSolve(elevator.getaimfloor(), elevator.getsendtime()); //调用ERSolve方法进行计算和判读啊
				if (sDirection.equals("ERROR3")) {  //不合礼的请求活无法服务的
					System.out.println("ERROR");
					System.out.println("#命令发送时间有误。");
				} else if (sDirection.equals("ERROR4")) {
					System.out.println("ERROR");
					System.out.println("#命令目标楼层有误。");
				} else {  //可以服务
					System.out.println( //把计算的结果进行输出
							"(" + elevator.getnowfloor() + "," + sDirection + "," + elevator.getendtime() + ")");
				}
			}
		}
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值