当前位置: 首页 > news >正文

设计模式の状态策略责任链模式

文章目录

  • 前言
  • 一、状态模式
  • 二、策略模式
  • 三、责任链模式


前言

  本篇是关于设计模式中的状态模式、策略模式、以及责任链模式的学习笔记。


一、状态模式

  状态模式是一种行为设计模式,核心思想在于,使某个对象在其内部状态改变时,改变该对象的行为,使对象看起来像是改变了其类。将状态的相关行为封装到独立的状态类中,并通过在运行时切换状态对象来改变对象的行为。实现方式在于,将状态抽取成单独的类,并由上下文类统一管理。
  状态模式的结构包括以下几个主要角色:

  1. 上下文类:它维护一个当前状态的实例,并且对客户端公开其接口。
  2. 抽象状态类:定义了所有具体状态类需要实现的接口,抽取出所有状态下共有的方法。
  3. 具体状态类:实现了抽象状态类,根据自身状态的特点,有选择性第重写父类方法的逻辑。

  假设需要设计一个抽奖系统,有四种状态:

  • 不能抽奖的状态
  • 可以抽奖的状态
  • 发放奖品的状态
  • 奖品发放完成的状态

  状态流转方式如下:
在这里插入图片描述  体现在代码上,首先设计一个抽象状态接口,该接口将各种状态下可能的操作进行聚合:

/*** 状态接口* 将各种状态下可能的操作聚合成一个接口* 实现类根据各自状态可能的业务去重写其中的方法*/
public interface State {/*** 扣除积分*/void deduceMoney();/*** 抽奖* @return*/boolean raffle();/*** 发放奖品*/void dispensePrice();
}

  抽象接口具体的实现
  不能抽奖状态,在此状态下只能去做出扣减积分的操作,扣减完成积分后,状态会变更为可抽奖状态

/*** 不能抽奖的状态*/
public class NoRaffleState implements State{RaffleActivity raffleActivity;public NoRaffleState(RaffleActivity raffleActivity) {this.raffleActivity = raffleActivity;}/*** 扣除积分*/@Overridepublic void deduceMoney() {System.out.println("扣除50积分,可以抽奖");raffleActivity.setState(raffleActivity.getCanRaffleState());}/*** 抽奖** @return*/@Overridepublic boolean raffle() {System.out.println("扣除积分方能抽奖");return false;}/*** 发放奖品*/@Overridepublic void dispensePrice() {System.out.println("不能发放奖品");}
}

  可抽奖状态,只能进行抽奖操作:

  • 未抽中奖品,重新回到不可抽奖状态
  • 抽中了奖品,流转到发送奖品状态
/*** 可以抽奖的状态*/
public class CanRaffleState implements State{RaffleActivity raffleActivity;public CanRaffleState(RaffleActivity raffleActivity) {this.raffleActivity = raffleActivity;}/*** 扣除积分*/@Overridepublic void deduceMoney() {System.out.println("已经扣除积分,可以抽奖");}/*** 抽奖** @return*/@Overridepublic boolean raffle() {System.out.println("正在抽奖,请稍等");int num = new Random().nextInt(10);if (num == 0){//中奖了,发放奖品raffleActivity.setState(raffleActivity.getDispenseState());return true;}else {System.out.println("很遗憾,您没有中奖");//回到不能抽奖的状态raffleActivity.setState(raffleActivity.getNoRaffleState());return false;}}/*** 发放奖品*/@Overridepublic void dispensePrice() {System.out.println("没中奖,不能发放奖品");}
}

  发放奖品状态,只能进行发放奖品的操作:

  • 奖品数量充足,流转到奖品发送完成状态。
  • 奖品数量不足,改变状态为不能抽奖
/*** 发放奖品的状态*/
public class DispenseState implements State{RaffleActivity raffleActivity;public DispenseState(RaffleActivity raffleActivity) {this.raffleActivity = raffleActivity;}/*** 扣除积分*/@Overridepublic void deduceMoney() {System.out.println("不能扣除积分");}/*** 抽奖** @return*/@Overridepublic boolean raffle() {System.out.println("不能抽奖");return false;}/*** 发放奖品*/@Overridepublic void dispensePrice() {if (raffleActivity.getCount()>0){System.out.println("恭喜中奖了");//改变状态为不能抽奖raffleActivity.setState(raffleActivity.getNoRaffleState());}else {System.out.println("很遗憾,奖品发送完了");//改变状态为奖品发送完成raffleActivity.setState(raffleActivity.getDispenseOutState());}}
}

  奖品发放完成,则不可以进行任何操作

/*** 奖品发放完成的状态*/
public class DispenseOutState implements State{RaffleActivity raffleActivity;public DispenseOutState(RaffleActivity raffleActivity) {this.raffleActivity = raffleActivity;}/*** 扣除积分*/@Overridepublic void deduceMoney() {System.out.println("奖品发送完了,请下次再参加");}/*** 抽奖** @return*/@Overridepublic boolean raffle() {System.out.println("奖品发送完了,请下次再参加");return false;}/*** 发放奖品*/@Overridepublic void dispensePrice() {System.out.println("奖品发送完了,请下次再参加");}
}

  创建一个上下文类,对状态进行统一管理,同时对状态进行初始化,并且上面的具体状态类,也聚合了上下文类的对象:

/*** 抽奖的行为*/
public class RaffleActivity {/*** 初始的状态*/State state = null;/*** 初始的数量*/int count = 0;State canRaffleState = new CanRaffleState(this);State noRaffleState = new NoRaffleState(this);State dispenseOutState = new DispenseOutState(this);State dispenseState = new DispenseState(this);public RaffleActivity(int count) {//初始状态,不能抽奖this.state = getNoRaffleState();this.count = count;}/*** 扣除积分*/public void deduceMoney(){state.deduceMoney();}/*** 抽奖*/public void raffle(){if (state.raffle()){//领取奖品state.dispensePrice();}}public State getState() {return state;}public void setState(State state) {this.state = state;}public int getCount() {int curCount = this.count;count--;return curCount;}public void setCount(int count) {this.count = count;}public State getCanRaffleState() {return canRaffleState;}public void setCanRaffleState(State canRaffleState) {this.canRaffleState = canRaffleState;}public State getNoRaffleState() {return noRaffleState;}public void setNoRaffleState(State noRaffleState) {this.noRaffleState = noRaffleState;}public State getDispenseOutState() {return dispenseOutState;}public void setDispenseOutState(State dispenseOutState) {this.dispenseOutState = dispenseOutState;}public State getDispenseState() {return dispenseState;}public void setDispenseState(State dispenseState) {this.dispenseState = dispenseState;}
}
public class Client {public static void main(String[] args) {RaffleActivity raffleActivity = new RaffleActivity(1);for (int i = 0; i < 3; i++) {//扣积分raffleActivity.deduceMoney();//抽奖raffleActivity.raffle();}}
}

小结
状态模式的优缺点
优点:

  • 遵循单一职责原则:将与状态相关的代码封装到独立类中。
  • 开闭原则:添加新状态非常方便,无需修改现有代码。
  • 消除大量条件语句:状态切换通过对象替换实现,而非复杂的条件判断。

缺点:

  • 类的数量增加:每个状态都需要创建一个类,可能导致类数量增多。
  • 状态之间的耦合:状态类之间可能需要频繁切换,会导致一定程度的耦合。

二、策略模式

  策略模式是一种行为设计模式,核心思想在于,定义了一组算法,将每个算法封装到独立的类中,使它们可以相互替换。
  策略模式通常包括以下角色:

  1. 上下文类:持有一个策略对象的引用,并且初始化具体策略。
  2. 抽象策略类:定义了所有具体策略类需要实现的接口。
  3. 具体策略类:实现抽象策略类,包含具体的算法或行为。

  假设目前有一个方法,需要根据参数中传入的不同的业务类型,执行不同业务的分派,如果使用传统方式,则会利用switch或者if-else实现,将来需要扩展的时候,需要对分支代码进行修改:

/*** 业务处理接口*/
public interface BusinessClass {/*** 处理业务*/void handleBusiness(int type);
}
public class BusinessClassImpl implements BusinessClass{/*** 处理业务* 根据传入的参数进行分发*/@Overridepublic void handleBusiness(int type) {switch (type){case 1:this.handleBusiness1();break;case 2:this.handleBusiness2();break;case 3:this.handleBusiness3();break;default:break;}}private void handleBusiness3() {System.out.println("业务3的具体逻辑");}private void handleBusiness2() {System.out.println("业务2的具体逻辑");}private void handleBusiness1() {System.out.println("业务1的具体逻辑");}
}

  使用策略模式改造,则可以抽取一个策略接口

/*** 业务策略接口*/
public interface BusinessStrategy {/*** 处理具体的业务逻辑*/void handleBusiness();
}

  将传统方式中,每个分支中的方法都抽取到一个单独的类中,实现策略接口

public class Business1 implements BusinessStrategy{/*** 处理具体的业务逻辑*/@Overridepublic void handleBusiness() {System.out.println("处理业务逻辑1");}
}
public class Business2 implements BusinessStrategy{/*** 处理具体的业务逻辑*/@Overridepublic void handleBusiness() {System.out.println("处理业务逻辑2");}
}
public class Business3 implements BusinessStrategy{/*** 处理具体的业务逻辑*/@Overridepublic void handleBusiness() {System.out.println("处理业务逻辑3");}
}

  在上下文类中,对其进行统一的管理,业务代码只需要注入上下文类,调用其中的方法即可。

public class Context {private Map<Integer, BusinessStrategy> strategyMap = new HashMap<>();/*** 初始化上下文,k业务类型 v 业务类型具体的逻辑*/public Context(){strategyMap.put(1, new Business1());strategyMap.put(2, new Business2());strategyMap.put(3, new Business3());}/*** 处理业务* 根据传入的参数进行分发*/public void handleBusiness(int type) {BusinessStrategy strategy = strategyMap.get(type);if (strategy != null) {strategy.handleBusiness();} else {System.out.println("无效的业务类型");}}
}

小结
策略模式的优缺点
优点:

  • 遵循开闭原则:添加新策略无需修改现有代码,只需扩展新策略类。
  • 消除条件语句:避免了复杂的 if-else 或 switch-case 语句。
  • 提高灵活性:客户端可以动态选择策略。

缺点:

  • 类数量增加:每种策略需要创建一个类,可能导致类的数量过多。
  • 客户端需要了解不同策略:客户端必须知道有哪些策略才能选择合适的策略。

三、责任链模式

  责任链模式是一种行为设计模式,核心目的在于,将请求的处理责任沿着一条链传递,直到有对象处理这个请求为止。责任链模式将请求的发送者和接收者解耦,且可以动态地调整链条上的处理顺序。
  责任链模式通常包含以下角色:

  1. 抽象处理者:定义了处理请求的接口,以及一个指向下一个处理者的引用。(即将自身作为属性存放在类中)
  2. 具体处理者:继承了抽象处理者,具体去实现各自处理请求的逻辑,以及无法处理时/处理完成时,应该调用的下一个处理者
  3. 客户端:创建并组装责任链,通常会将请求发送给责任链的首个处理者

  下面来看一个案例:假设某个学校,购买教材,器材,根据金额不同,需要审批的级别也不同。
  首先构建一个请求对象

public class Request {/*** 请求id*/protected int id = 0;/*** 价格*/protected int price = 0;public Request() {}public Request(int id, int price) {this.id = id;this.price = price;}public int getId() {return id;}public void setId(int id) {this.id = id;}public int getPrice() {return price;}public void setPrice(int price) {this.price = price;}
}

  然后定义一个抽象处理者

/*** 抽象审批人*/
public abstract class Approver {/*** 审批人名称*/protected String name;/*** 持有自己的引用*/protected Approver approver;public Approver() {}public Approver(String name) {this.name = name;}public void setApprover(Approver approver) {this.approver = approver;}/*** 子类具体去实现处理请求的逻辑* @param request*/abstract void handleReq(Request request);}

  定义具体处理人,继承抽象处理人,编写自己处理的判断逻辑:

public class TeachingDirector extends Approver{public TeachingDirector(String name){super(name);}/*** 子类具体去实现处理请求的逻辑** @param request*/@Overridevoid handleReq(Request request) {if (request.getPrice()<= 5000){System.out.println("请求编号"+ request.id + "已经被" + name + "处理");}else {approver.handleReq(request);}}
}
public class Dean extends Approver{public Dean(String name){super(name);}/*** 子类具体去实现处理请求的逻辑** @param request*/@Overridevoid handleReq(Request request) {if (request.getPrice()<= 10000){System.out.println("请求编号"+ request.id + "已经被" + name + "处理");}else {approver.handleReq(request);}}
}
public class Principal extends Approver{public Principal(String name){super(name);}/*** 子类具体去实现处理请求的逻辑** @param request*/@Overridevoid handleReq(Request request) {if (request.getPrice()<= 20000){System.out.println("请求编号"+ request.id + "已经被" + name + "处理");}else {approver.handleReq(request);}}
}

  最后由客户端对其进行统一组装:

public class Client {public static void main(String[] args) {Request request = new Request(1, 8000);Dean dean = new Dean("院长");TeachingDirector teachingDirector = new TeachingDirector("教学主任");Principal principal = new Principal("校长");//设置下一个审批者teachingDirector.setApprover(dean);dean.setApprover(principal);principal.setApprover(teachingDirector);//8000 教学主任处理不了,交给下一级(院长)处理teachingDirector.handleReq(request);}
}

小结
责任链模式的优缺点

优点:

  • 降低耦合度:请求发送者与接收者解耦,无需关心由谁处理请求。
  • 动态灵活:可以在运行时动态调整责任链的结构。
  • 增强扩展性:新增处理者无需修改现有代码。

缺点:

  • 链条可能过长:请求可能需要经过多个处理者,性能可能受影响。
  • 调试困难:由于请求的处理流程不明确,可能导致调试复杂。

相关文章:

设计模式の状态策略责任链模式

文章目录 前言一、状态模式二、策略模式三、责任链模式 前言 本篇是关于设计模式中的状态模式、策略模式、以及责任链模式的学习笔记。 一、状态模式 状态模式是一种行为设计模式&#xff0c;核心思想在于&#xff0c;使某个对象在其内部状态改变时&#xff0c;改变该对象的行为…...

DevOps流程CICD之Jenkins使用操作

一、jenkins的docker-compose安装部署 请参考 jenkins的docker安装部署配置全网最详细教程-CSDN博客 二、创建repository 三、创建ssh 四、创建视图 五、创建任务 六、配置gitlab钩子 七、自动构建部署CI/CD验证...

【玩转23种Java设计模式】行为型模式篇:备忘录模式

软件设计模式&#xff08;Design pattern&#xff09;&#xff0c;又称设计模式&#xff0c;是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 汇总目录链接&…...

Unity Shader TexelSize的意义

TexelSize在制作玻璃折射效果时会用到。 // Get the normal in tangent space fixed3 bump UnpackNormal(tex2D(_BumpMap, i.uv.zw)); // Compute the offset in tangent space float2 offset bump.xy * _Distortion * _RefractionTex_TexelSize.xy; i.scrPos.xy offset * i…...

三、STM32MP257系列之定制Yocto Machine

文章目录 STM32MP257系列之定制的Yocto Machine1. TFA 定制2. OPTEE OS定制3. Uboot 定制3.1 创建 board3.2 创建 board的头文件3.3 创建 board的配置文件3.4 添加我们自己的dtb文件3.5 生成新patch打包到uboot recipe中3.6 修改yocto中的配置 4. Kernel 定制4.1 定制设备树 5.…...

小程序信息收集(小迪网络安全笔记~

免责声明&#xff1a;本文章仅用于交流学习&#xff0c;因文章内容而产生的任何违法&未授权行为&#xff0c;与文章作者无关&#xff01;&#xff01;&#xff01; 附&#xff1a;完整笔记目录~ ps&#xff1a;本人小白&#xff0c;笔记均在个人理解基础上整理&#xff0c;…...

使用 Docker 搭建 Drogon 框架

使用 Docker 搭建 Drogon 框架 Drogon 是一个基于 C 的高性能 Web 框架&#xff0c;支持异步 I/O 和协程。使用 Docker 可以快速搭建 Drogon 开发环境&#xff0c;避免依赖冲突和配置问题。 以下是使用 Docker 搭建 Drogon 框架的详细步骤&#xff1a; 1. 准备工作 安装 Doc…...

【Linux报告】实训一:GNME桌面环境的设置及应用

实训一&#xff1a;GNME桌面环境的设置及应用 【练习1】在图形模式和文本模式下登录Linux系统。 1、开启Linux虚拟机。 答&#xff1a;打开此虚拟机如图所示 2、观察屏幕上显示的启动信息。 3、当系统启动到图形界面时&#xff0c;用普通用户身份登录。 答&#xff1a;如图…...

活动预告 |【Part1】Microsoft Azure 在线技术公开课:基础知识

课程介绍 参加“Azure 在线技术公开课&#xff1a;基础知识”活动&#xff0c;培养有助于创造新的技术可能性的技能并探索基础云概念。参加我们举办的本次免费培训活动&#xff0c;扩充自身的云模型和云服务类型知识。你还可以查看以计算、网络和存储为核心的 Azure 服务。 活…...

vulnhub靶场【Hogwarts】之bellatrix

前言 靶机&#xff1a;hotwarts-dobby&#xff0c;ip地址为192.168.1.69 攻击&#xff1a;kali&#xff0c;ip地址为192.168.1.16 都采用虚拟机&#xff0c;网卡为桥接模式 主机发现 使用arp-scan -l或netdiscover -r 192.168.1.1/24扫描发现主机 信息收集 使用nmap扫描端…...

移动 APP 设计规范参考

一、界面设计规范 布局原则&#xff1a; 内容优先&#xff1a;以内容为核心进行布局&#xff0c;突出用户需要的信息&#xff0c;简化页面导航&#xff0c;提升屏幕空间利用率.一致性&#xff1a;保持界面元素风格一致&#xff0c;包括颜色、字体、图标等&#xff0c;使用户在…...

HarmonyOS:@Require装饰器:校验构造传参

一、前言 Require是校验Prop、State、Provide、BuilderParam和普通变量(无状态装饰器修饰的变量)是否需要构造传参的一个装饰器。 说明 从API version 11开始对Prop/BuilderParam进行校验。 从API version 11开始&#xff0c;该装饰器支持在元服务中使用。 从API version 12开…...

github提交不上去,网络超时问题解决

问题出现的原因&#xff1a; DNS服务器数据不同步&#xff0c;github的服务器发送迁移&#xff0c;在本地缓存的ip地址现在无效了。 解决方案&#xff1a; 1&#xff09;点击这里&#xff0c;查询github.com最新的ip地址 2.0&#xff09;编辑linux系统地址缓存文件&#x…...

国产数据库OceanBase从入门到放弃教程

1. 介绍 是由蚂蚁集团&#xff08;Ant Group&#xff0c;原蚂蚁金服&#xff09;自主研发的分布式关系型数据库。它旨在解决海量数据存储和高并发访问的问题&#xff0c;特别适合金融级应用场景&#xff0c;如支付宝等对数据一致性、可靠性和性能有极高要求的服务。以下是关于…...

风力涡轮机缺陷检测数据集,91.4%准确识别率,18912张图片,支持yolo,PASICAL VOC XML,COCO JSON格式的标注

风力涡轮机缺陷检测数据集&#xff0c;91.4&#xff05;准确识别率&#xff0c;18912张图片&#xff0c;支持yolo&#xff0c;PASICAL VOC XML&#xff0c;COCO JSON格式的标注 数据集下载&#xff1a; &#xff59;&#xff4f;&#xff4c;&#xff4f; &#xff56;&#…...

Rabbitmq追问2

分析rabbitmq 默认使用姿势是什么 direct fanout还是什么 public void convertAndSend(String exchange, String routingKey, Object object, CorrelationData correlationData) throws AmqpException { this.send(exchange, routingKey, this.convertMessageIfNecessary(obje…...

郑州时空-TMS运输管理系统 GetDataBase 信息泄露漏洞复现

0x01 产品简介 郑州时空-TMS运输管理系统是一款专为物流运输企业设计的综合性管理软件,旨在提高运输效率、降低运输成本,并实现供应链的协同运作。系统基于现代计算机技术和物流管理方法,结合了郑州时空公司的专业经验和技术优势,为物流运输企业提供了一套高效、智能的运输…...

如何使用React,透传各类组件能力/属性?

在23年的时候&#xff0c;我主要使用的框架还是Vue&#xff0c;当时写了一篇“如何二次封装一个Vue3组件库&#xff1f;”的文章&#xff0c;里面涉及了一些如何使用Vue透传组件能力的方法。在我24年接触React之后&#xff0c;我发现这种扩展组件能力的方式有一个专门的术语&am…...

汇编点灯练习

要求&#xff1a; 1、轮流将LED1、LED2、LED3及蜂鸣器点亮 2、基于STM32MP157AAA&#xff0c;阅读原理图和STM32MP157芯片手册 3、ARM汇编指令点灯 1、运行效果 汇编点灯 2、通过查询原理图和芯片手册&#xff0c;得到以下结论&#xff1a; 3、汇编源码 .text .global _start…...

数据结构与算法之动态规划: LeetCode 213. 打家劫舍 II (Ts版)

打家劫舍 II https://leetcode.cn/problems/house-robber-ii/description/ 描述 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋&#xff0c;每间房内都藏有一定的现金这个地方所有的房屋都 围成一圈 &#xff0c;这意味着第一个房屋和最后一个房屋是紧挨着的同时&#…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...