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

C# 迭代,递归,回调--13

目录

一.迭代

迭代器示例:

关键点:

优势:

二.递归

递归示例:

关键点:

优势:

注意:

三.回调

回调示例:

关键点:

优势:

应用场景:

4.三种模式的特点对比:

迭代:

递归:

回调:


一.迭代

在C#中迭代通常指重复执行一系列指令

在C#中,迭代器是一种特殊的结构,允许我们自定义遍历集合的方式,主要使用yield return关键字

yield return关键字的主要优点包括:

  • 简化了迭代器的实现:不需要手动维护状态或创建临时集合
  • 提高了代码的可读性和可维护性:使用 yield return 的方法显得更加直观
  • 延迟执行:元素在需要时才生成,适合处理大量数据或计算密集型操作

除了 yield return,还有一个相关的关键字 yield break,用于终止迭代器并退出迭代

迭代器示例:

class Program
{static void Main(string[] args){Console.WriteLine("迭代器示例:\n");// 1. 使用迭代器方法Console.WriteLine("1. 斐波那契数列(前10个数):");foreach (var num in Fibonacci(10)){Console.Write($"{num} ");}Console.WriteLine("\n");// 2. 自定义集合迭代var customCollection = new CustomCollection(5);Console.WriteLine("2. 自定义集合迭代:");foreach (var item in customCollection){Console.Write($"{item} ");}Console.WriteLine("\n");// 3. yield return 示例Console.WriteLine("3. 生成偶数序列(0-10):");foreach (var even in GetEvenNumbers(10)){Console.Write($"{even} ");}Console.WriteLine("\n");// 4. 带条件的迭代器Console.WriteLine("4. 按条件过滤的数字(1-20中能被3整除的数):");foreach (var num in GetNumbersDivisibleBy3(20)){Console.Write($"{num} ");}Console.WriteLine("\n");Console.ReadKey();}// 斐波那契数列迭代器static IEnumerable<int> Fibonacci(int count){int current = 0, next = 1;for (int i = 0; i < count; i++){yield return current;int temp = current + next;current = next;next = temp;}}// 生成偶数的迭代器static IEnumerable<int> GetEvenNumbers(int max){for (int i = 0; i <= max; i++){if (i % 2 == 0)yield return i;}}// 能被3整除的数的迭代器static IEnumerable<int> GetNumbersDivisibleBy3(int max){for (int i = 1; i <= max; i++){if (i % 3 == 0)yield return i;}}
}// 自定义可迭代集合
class CustomCollection : IEnumerable<int>
{private int[] array;public CustomCollection(int size){array = new int[size];for (int i = 0; i < size; i++){array[i] = i * i; // 存储数字的平方}}public IEnumerator<int> GetEnumerator(){for (int i = 0; i < array.Length; i++){yield return array[i];}}System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator(){return GetEnumerator();}
}

关键点:

  • 循环结构: 在C#中,迭代通常通过forwhiledo...whileforeach等循环结构实现

  • 用途: 用于在数量已知或者条件可判定的情况下重复执行某段代码,例如遍历数组、执行固定次数的计算等

  • 控制条件: 迭代需要有明确的开始条件、结束条件,以及每次迭代时的状态更新,避免出现无限循环

优势:

  • 可控性强: 通过明确的控制条件,可以精确地控制迭代次数
  • 效率高: 迭代通常比递归占用更少的内存,因为不涉及函数调用的堆栈开销

二.递归

递归是指函数在其定义中直接或间接调用自身的编程技巧

递归通常用于解决可以分解为相同子问题的问题,如阶乘,斐波那契数列等

递归示例:

class Program
{static void Main(string[] args){Console.WriteLine("递归示例演示:\n");// 1. 阶乘计算int n = 5;Console.WriteLine($"1. {n}的阶乘是: {CalculateFactorial(n)}");// 2. 斐波那契数列int position = 8;Console.WriteLine($"\n2. 斐波那契数列第{position}个数是: {Fibonacci(position)}");// 3. 数组求和int[] numbers = { 1, 2, 3, 4, 5 };Console.WriteLine($"\n3. 数组求和结果: {ArraySum(numbers, numbers.Length - 1)}");// 4. 字符串反转string text = "Hello, World!";Console.WriteLine($"\n4. 字符串 \"{text}\" 反转后: {ReverseString(text)}");// 5. 最大公约数int a = 48, b = 36;Console.WriteLine($"\n5. {a}和{b}的最大公约数是: {GCD(a, b)}");// 6. 汉诺塔问题Console.WriteLine("\n6. 汉诺塔移动步骤(3个盘子):");HanoiTower(3, 'A', 'B', 'C');// 7. 目录结构显示Console.WriteLine("\n7. 显示目录结构:");string path = @"C:\Example"; // 替换为实际路径try{ShowDirectoryStructure(path, 0);}catch (Exception ex){Console.WriteLine($"读取目录时出错: {ex.Message}");}Console.ReadKey();}// 1. 计算阶乘static int CalculateFactorial(int n){if (n <= 1) return 1;return n * CalculateFactorial(n - 1);}// 2. 斐波那契数列static int Fibonacci(int n){if (n <= 1) return n;return Fibonacci(n - 1) + Fibonacci(n - 2);}// 3. 数组求和static int ArraySum(int[] array, int index){if (index < 0) return 0;return array[index] + ArraySum(array, index - 1);}// 4. 字符串反转static string ReverseString(string str){if (string.IsNullOrEmpty(str) || str.Length <= 1)return str;return ReverseString(str.Substring(1)) + str[0];}// 5. 最大公约数(欧几里得算法)static int GCD(int a, int b){if (b == 0) return a;return GCD(b, a % b);}// 6. 汉诺塔问题static void HanoiTower(int n, char from, char auxiliary, char to){if (n == 1){Console.WriteLine($"将盘子 1 从 {from} 移动到 {to}");return;}HanoiTower(n - 1, from, to, auxiliary);Console.WriteLine($"将盘子 {n} 从 {from} 移动到 {to}");HanoiTower(n - 1, auxiliary, from, to);}// 7. 显示目录结构static void ShowDirectoryStructure(string path, int level){// 添加缩进string indent = new string(' ', level * 2);try{// 显示当前目录DirectoryInfo dir = new DirectoryInfo(path);Console.WriteLine($"{indent}[{dir.Name}]");// 显示文件foreach (FileInfo file in dir.GetFiles()){Console.WriteLine($"{indent}  {file.Name}");}// 递归显示子目录foreach (DirectoryInfo subDir in dir.GetDirectories()){ShowDirectoryStructure(subDir.FullName, level + 1);}}catch (UnauthorizedAccessException){Console.WriteLine($"{indent}访问被拒绝");}}
}

关键点:

  • 基例(终止条件): 递归必须要有一个明确的终止条件,即基例,否则会导致无限递归

  • 递归关系: 问题的解可以表示为其子问题的解的组合

  • 堆栈开销: 每一次递归调用都会在调用栈中存储当前函数的状态,深入太深可能导致栈溢出

优势:

  • 代码简洁: 对于某些问题,递归能使代码更易读、更简洁
  • 自然适应某些算法: 如树的遍历、分治算法等,递归实现更符合逻辑

注意:

  • 效率问题: 递归可能导致大量的函数调用,增加开销。
  • 栈溢出风险: 如果递归深度太大,可能导致栈溢出错误。

三.回调

回调是指将一个函数作为参数传递给另一个函数,当特定事件发生或条件满足时调用该函数

在C#中,回调通常通过委托事件来实现

回调示例:

class Program
{// 定义委托类型public delegate void ProcessCompleted(string result);public delegate int CalculateDelegate(int x, int y);static void Main(string[] args){Console.WriteLine("回调示例:\n");// 1. 使用委托回调Console.WriteLine("1. 委托回调示例:");ProcessCompleted callback = ShowResult;ProcessWithCallback("任务1", callback);// 2. 使用Action/FuncConsole.WriteLine("\n2. Action/Func回调示例:");ProcessWithAction("任务2", (result) => {Console.WriteLine($"Lambda回调结果: {result}");});// 3. 事件回调var processor = new TaskProcessor();processor.OnCompleted += (sender, result) => {Console.WriteLine($"事件回调结果: {result}");};processor.StartProcess("任务3");// 4. 异步回调Console.WriteLine("\n4. 异步回调示例:");AsyncProcessDemo().Wait();// 5. 计算器回调示例Console.WriteLine("\n5. 计算器回调示例:");CalculateWithCallback(10, 5, Add);CalculateWithCallback(10, 5, Subtract);Console.ReadKey();}// 基本回调方法static void ShowResult(string result){Console.WriteLine($"普通回调结果: {result}");}// 使用委托的处理方法static void ProcessWithCallback(string input, ProcessCompleted callback){// 模拟处理过程Thread.Sleep(100);string result = $"处理完成: {input}";callback(result);}// 使用Action的处理方法static void ProcessWithAction(string input, Action<string> callback){Thread.Sleep(100);string result = $"处理完成: {input}";callback(result);}// 异步回调示例static async Task AsyncProcessDemo(){await ProcessAsync("异步任务", (result) =>{Console.WriteLine($"异步回调结果: {result}");});}static Task ProcessAsync(string input, Action<string> callback){return Task.Run(() =>{Thread.Sleep(100);string result = $"处理完成: {input}";callback(result);});}// 计算器回调方法static int Add(int x, int y) => x + y;static int Subtract(int x, int y) => x - y;static void CalculateWithCallback(int x, int y, CalculateDelegate callback){int result = callback(x, y);Console.WriteLine($"计算结果: {result}");}
}// 使用事件的处理器类
class TaskProcessor
{public event EventHandler<string> OnCompleted;public void StartProcess(string input){// 模拟处理过程Thread.Sleep(100);string result = $"处理完成: {input}";// 触发事件OnCompleted?.Invoke(this, result);}
}

关键点:

  • 委托(Delegate): 在C#中,回调通常通过委托实现,委托是对函数的引用,可以作为参数传递

  • 事件(Event): 事件是委托的特殊形式,用于发布和订阅机制,常用于GUI编程、异步操作等

  • 异步编程: 回调在异步编程中非常重要,可以在异步操作完成后执行后续处理

优势:

  • 解耦: 回调机制使得调用者和被调用者之间的依赖减少,代码更加灵活
  • 灵活性: 可以在运行时决定调用哪个函数,增强了代码的可扩展性

应用场景:

  • 事件处理: 例如按钮点击事件,网络请求完成事件等
  • 异步操作: 在异步编程中,回调函数用于在任务完成后继续执行后续逻辑

4.三种模式的特点对比:

迭代:

        特点:

  • 逐个处理元素
  • 内存效率高
  • 代码直观

        适用场景:

  • 集合遍历
  • 简单重复操作
  • 需要延迟计算

递归:

        特点:

  • 自调用
  • 代码简洁
  • 需要注意栈溢出

        适用场景:

  • 树形结构处理
  • 分治算法
  • 自然递归问题

回调:

        特点:

  • 灵活可配置
  • 解耦操作
  • 支持异步

        适用场景:

  • 事件处理
  • 异步操作
  • 策略模式

策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以互相替换。策略模式使得算法可以在不影响客户端的情况下发生变化。它通过定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换,从而让算法的变化不会影响到使用算法的客户。

相关文章:

C# 迭代,递归,回调--13

目录 一.迭代 迭代器示例: 关键点: 优势: 二.递归 递归示例: 关键点: 优势: 注意: 三.回调 回调示例: 关键点: 优势: 应用场景: 4.三种模式的特点对比: 迭代: 递归: 回调: 一.迭代 在C#中迭代通常指重复执行一系列指令 在C#中,迭代器是一种特殊的结构,允许…...

海康大数据面试题及参考答案

请详细描述 YARN 提交程序的流程。 YARN(Yet Another Resource Negotiator)是一个资源管理系统,用于管理集群中的计算资源。以下是在 YARN 中提交程序的详细流程: 首先是客户端准备阶段。用户编写好应用程序,这个程序可以是 MapReduce、Spark 或者其他基于 YARN 的计算框架…...

软件测试 —— 自动化测试(Selenium)

软件测试 —— 自动化测试&#xff08;Selenium&#xff09; 什么是SeleniumPython安装Selenium1.安装webdirver-manager2.安装Selenium 写一个简单用例CSS_SELECTOR和XPATH浏览器快速定位页面元素浏览器的前进&#xff08;forward&#xff09;&#xff0c;后退&#xff08;bac…...

华为2024嵌入式研发面试题

01 你认为最好的排序算法是什么&#xff1f; 在实际的编程中&#xff0c;最好的排序算法要根据实际需求和数据规模来选择&#xff0c;因为每种排序算法都有其优势和劣势。以下是一些常见排序算法及其优缺点&#xff1a; 冒泡排序 冒泡排序是一种简单直观的排序算法&#xff0…...

centos 搭建nginx+配置域名+windows访问

准备工作&#xff1a;一个完整的centos环境&#xff0c;nginx安装包(可以从官网下载)nginx: download 一&#xff1a;centos可能有精简版&#xff0c;部分环境没有相关依赖包&#xff0c; 需要检查以下项&#xff1a; 1.gcc检查&#xff1a;gcc -v&#xff08;回车后应当有版…...

APP推荐:全新TV端来了,8K原画电视版

▌ 软件介绍 B站都不陌生吧&#xff0c;一个能追番、学习、娱乐的多元平台&#xff0c;之前也分享过几款第三方TV端&#xff0c;其中的BV最近更新了全新版本。 使用了全新的UI界面&#xff0c;由之前的顶部菜单栏改成了侧边布局&#xff0c;已解锁限制&…...

【MySQL】索引(一)

索引 一、磁盘1、物理结构2、示意图3、定位扇区4、读写操作的基本方式 二、页1、介绍2、示例3、作用与结构4、类型&#xff08;1&#xff09;数据页&#xff08;2&#xff09;其他 5、组织与管理6、性能优化7、示意图&#xff08;B树&#xff09; 三、索引1、作用2、注意事项 四…...

ES6的高阶语法特性

一、模板字符串的高级用法 1.1.模板字符串的嵌套 模板字符串的嵌套允许在一个模板字符串内部再嵌入一个或多个模板字符串。这种嵌套结构在处理复杂数据结构或生成具有层级关系的文本时非常有用。 1. 嵌套示例 假设我们有一个包含多个对象的数组&#xff0c;每个对象都有名称、…...

GO:GO程序如何处理缓存加载和大数据缓存

如果我们会在程序启动时&#xff0c;需要加载所有数据&#xff0c;最简单的方式就是程序启动&#xff0c;通过轮训从数据库拉取所有数据&#xff0c;并写入到本地缓存中。 问题&#xff1a;数据量较大的时候&#xff0c;程序加载慢&#xff0c;启动时间长&#xff0c;遇到问题不…...

时序数据库TDengine 3.3.5.0 发布:高并发支持与增量备份功能引领新升级

近日&#xff0c;TDengine 3.3.5.0 版本正式发布&#xff0c;带来了多项重磅更新与优化&#xff0c;从功能拓展到性能提升&#xff0c;再到用户体验进行了全面改进。本次更新围绕用户核心需求展开&#xff0c;涵盖了开发工具、数据管理、安全性、可视化等多个层面&#xff0c;为…...

信息系统项目管理-采购管理-采购清单示例

序号类别产品/服务名称规格/功能描述数量备注1硬件服务器高性能处理器&#xff0c;大容量存储10HP、DELL2网络设备高速路由器和交换机10华为3工作站多核处理器&#xff0c;高分辨率显示器25国产设备4移动检查设备手持式移动检查仪&#xff0c;可连接云平台30国产设备5打印机和扫…...

python识别图片中指定颜色的图案并保存为图片

示例代码&#xff1a; def chuli(color):import cv2import numpy as np# 定义颜色名称到HSV阈值范围的映射color_thresholds {red: ([0, 100, 100], [10, 255, 255], [160, 100, 100], [180, 255, 255]),yellow: ([20, 100, 100], [30, 255, 255]),blue: ([90, 100, 100], [1…...

【git命令行】git pull冲突如何使用stash暂存,不提交当前工作的情况下临时保存修改

1、git add . 暂存区暂存 2、git stash save "message" 保存当前工作目录的临时状态&#xff0c;并将其存储为一个新的stash 3 、git pull 重新拉取 4、**git stash pop**吐出之前暂存的改动&#xff0c;git stash clear 清空所有暂存...

浏览器输入http形式网址后自动跳转https解决方法

一、问题描述 使用浏览器 网上冲浪 时会遇到一个情况&#xff1a; 在浏览器中输入“http域名”后会自动变成“https 域名”的形式&#xff0c;此时“https 域名”的网站可能已停止对外提供服务了&#xff0c;这时会出现如下不友好的网页提示&#xff1a; 二、处理方法&#x…...

BertTokenizerFast 和 BertTokenizer 的区别

BertTokenizerFast 和 BertTokenizer 都是用于对文本进行标记化的工具&#xff0c;主要用于处理和输入文本数据以供 BERT 模型使用。它们都属于 HuggingFace 的 transformers 库。 主要区别 底层实现&#xff1a; BertTokenizer: 这是一个使用纯 Python 实现的标记器&#xff…...

【update 更新数据语法合集】.NET开源ORM框架 SqlSugar 系列

系列文章目录 &#x1f380;&#x1f380;&#x1f380; .NET开源 ORM 框架 SqlSugar 系列 &#x1f380;&#x1f380;&#x1f380; 文章目录 系列文章目录前言 &#x1f343;一、实体对象更新1.1 单条与批量1.2 不更新某列1.3 只更新某列1.4 NULL列不更新1.5 无主键/指定列…...

测试人员面试需要掌握的内容

测试人员面试需要掌握的内容 1、在公司的测试流程是什么&#xff1f; 产品经理确认本次版本的需求&#xff0c;召开需求评审会&#xff0c;进行估时排期&#xff0c;需求和时间都确定之后&#xff0c;UI出设计图&#xff0c;开发人员进行开发&#xff0c;测试人员编写测试用例…...

git 新建分支并推到远程分支

在git或者码云上创建一个项目管理&#xff0c;已经存在主分支&#xff0c;现在需要创建一个其他分支&#xff1b; 具体操作&#xff1a; 1. 查看分支情况 git branch 2. 查看分支状态 git status 3. 一次性创建并切换到本地分支 git checkout -b dev 分步骤创建和切换&…...

【Uniapp-Vue3】showLoading加载和showModal模态框示例

一、showLoading加载 uni.showLoading({ title:"标题", // 其他配置 }); uni.hideLoading(); showLoading开启后不会自动关闭&#xff0c;只能手动配置uni.hideLoading() 来关闭加载框。 二、showModel模态框 uni.showModel({ title:"标题", // 其他配置 …...

PythonOpenCV图片识别

在windows下面&#xff0c;使用python opencv 进行识别&#xff0c;获取到坐标。 依赖安装&#xff1a; pip install opencv-python pip install numpy pip install pyautogui pip install pywin32代码&#xff1a; import cv2 import numpy as np import pyautogui import o…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...