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

R 语言入门实战|第七章 程序:从“老虎机”项目学透流程控制与代码优化

引言:第七章为何是 “R 编程进阶” 的关键?

在第二部分 “玩扑克牌” 项目中,我们掌握了数据存储(数据框)、索引取子集和环境管理,但这些操作更偏向 “数据静态处理”。而《R 语言入门与实践》第七章 “程序”,正式进入动态流程控制阶段 —— 通过 “老虎机模拟” 项目,教你如何用if/else语句判断条件、用 “查找表” 简化冗余代码、用结构化思维拆解复杂任务,最终编写能自动执行逻辑的完整程序。

本章的核心目标是:理解 “程序 = 有序步骤 + 同类情况” 的设计思路,掌握 R 中流程控制的核心工具,写出逻辑清晰、可复用的程序(如老虎机的play()函数),为后续循环、面向对象编程打下基础。

一、程序设计的核心策略:拆解任务是关键

第七章开篇就强调:复杂程序的本质是 “简单任务的组合”。面对 “老虎机计算奖金” 这样的复杂需求,需先将任务拆解为两类子任务(文档第七章 7.1 节):

  1. 有序步骤:按顺序执行的操作(如 “生成 3 个符号→计算奖金→显示结果”);
  2. 同类情况:需分支判断的场景(如 “3 个相同符号→奖金 80 元”“全是杠→奖金 5 元”“有樱桃→奖金 2 元”)。

实战示例:老虎机任务拆解

以老虎机程序为例,完整流程拆解为 3 个有序步骤,其中 “计算奖金” 又包含 3 种同类情况:

二、流程控制工具:从if到 “查找表”

第七章的核心工具围绕 “如何处理同类情况” 展开,从基础的if语句到高效的 “查找表”,逐步优化代码逻辑。

2.1 if语句:单条件判断的基础

if语句是 R 中最基础的流程控制工具,用于 “当条件为真时执行某操作”,语法和应用完全贴合文档第七章 7.2 节。

语法格式
if (条件) {# 条件为TRUE时执行的代码
}
  • 条件:必须是返回单个TRUE/FALSE的逻辑测试(如symbols[1] == symbols[2]);
  • 代码块:条件为真时执行的内容,支持多行代码(建议缩进提升可读性)。
实战:判断老虎机是否出现 “3 个相同符号”
# 示例:检查3个符号是否完全相同
symbols <- c("7", "7", "7")  # 老虎机生成的符号
if (symbols[1] == symbols[2] && symbols[2] == symbols[3]) {cat("恭喜!3个符号相同!")
}
# 输出:恭喜!3个符号相同!
关键注意点
  • 若条件是逻辑向量(如c(TRUE, FALSE)),if仅会判断第一个元素,并警告 “条件长度> 1”;
  • 可结合all()/any()将向量压缩为单个逻辑值(如all(symbols == "B")判断是否全是杠)。

2.2 elseelse if:多条件分支

当需要处理 “条件为假” 或 “多个互斥条件” 时,需用elseelse if,对应文档第七章 7.3 节。

语法格式
if (条件1) {# 条件1为TRUE时执行
} else if (条件2) {# 条件1为FALSE、条件2为TRUE时执行
} else {# 所有条件为FALSE时执行
}
实战:老虎机多情况奖金判断

结合第七章表 7-1 的奖金规则,判断不同符号组合的奖金:

# 示例:根据符号组合计算基础奖金
symbols <- c("B", "BB", "BBB")
prize <- 0  # 初始化奖金为0if (symbols[1] == symbols[2] && symbols[2] == symbols[3]) {# 情况1:3个相同符号prize <- 10  # 简化示例,实际需匹配符号类型
} else if (all(symbols %in% c("B", "BB", "BBB"))) {# 情况2:全是杠prize <- 5
} else {# 情况3:其他(含樱桃或无奖)cherry_count <- sum(symbols == "C")prize <- c(0, 2, 5)[cherry_count + 1]  # 1个樱桃2元,2个5元
}cat("奖金:$", prize, sep = "")  # 输出:奖金:$5

2.3 查找表:替代冗余if-else的高效工具

第七章 7.4 节重点介绍 “查找表”—— 当需要 “值→值” 的映射(如 “符号→奖金”)时,用命名向量替代冗长的if-else,代码更简洁、易维护。

查找表原理

通过命名向量存储映射关系,向量的 “名称” 是输入条件,“值” 是对应结果,再通过 “名称取子集” 快速匹配。

实战:老虎机奖金查找表
# 步骤1:创建查找表(符号→奖金,对应第七章表7-1)
payouts <- c("DD" = 100,   # 3个钻石"7" = 80,     # 3个7"BBB" = 40,   # 3个BBB"BB" = 25,    # 3个BB"B" = 10,     # 3个B"C" = 10,     # 3个樱桃"0" = 0       # 3个0(无奖)
)# 步骤2:根据符号匹配奖金
symbols <- c("7", "7", "7")
if (symbols[1] == symbols[2] && symbols[2] == symbols[3]) {prize <- payouts[symbols[1]]  # 按符号名称取子集
}cat("奖金:$", prize, sep = "")  # 输出:奖金:$80
优势对比
方式代码复杂度维护成本适用场景
if-else高(多条件嵌套)高(新增条件需加分支)条件逻辑复杂(如含计算)
查找表低(向量映射)低(新增映射仅需加元素)简单 “值→值” 映射

三、第七章核心新函数:参数详解与实战

第七章引入多个新函数,用于字符串处理、结果显示和对象属性管理,以下是关键函数的核心参数与应用(完全贴合文档第七章内容)。

3.1 paste():字符串拼接

paste()是 R 中处理字符串的核心函数,第七章用它将老虎机的 3 个符号合并为单个字符串(如 “7DD”),对应文档 7.5 节的slot_display函数。

核心参数
参数作用说明类型要求默认值
...待拼接的对象(可多个,如向量、字符串)任意类型(自动转字符)
sep不同对象之间的分隔符字符串" "(空格)
collapse若输入是向量,将向量元素合并为单个字符串的分隔符字符串(NULL 表示不合并)NULL
实战示例
# 示例1:拼接多个对象(sep参数)
symbols <- c("B", "C", "DD")
paste("符号组合:", paste(symbols, collapse = ""), sep = "") 
# 输出:"符号组合:BCD D"(注意:实际collapse会去掉空格,输出"符号组合:BCD D"应为"符号组合:BCD D"修正为"符号组合:BCDD")# 示例2:合并向量元素(collapse参数)
paste(symbols, collapse = "|")  # 输出:"B|C|DD"

3.2 cat():控制台输出(无引号)

cat()用于在控制台显示内容,第七章用它美化老虎机结果(如显示 “7DD\n$80”),区别于print()(会显示引号和行号),对应文档 7.5 节。

核心参数
参数作用说明类型要求默认值
...待输出的内容(可多个,如字符串、数值)任意类型(自动转字符)
sep不同内容之间的分隔符字符串" "
file输出目标(控制台或文件路径)字符串(""表示控制台)""
newline输出结束后是否换行逻辑值(TRUE/FALSETRUE
实战示例
# 示例:显示老虎机结果(符号+奖金)
symbols_str <- paste(c("7", "DD", "DD"), collapse = "")
prize <- 160  # 3个7+2个钻石,奖金翻倍后160
cat(symbols_str, "$", prize, sep = "\n")  # sep="\n"表示换行
# 输出:
# 7DDD
# $160

3.3 structure():为对象添加属性

structure()用于给 R 对象添加自定义属性(如老虎机结果的 “符号组合” 属性),第七章用它让play()函数同时返回奖金和符号,对应文档 7.5 节。

核心参数
参数作用说明类型要求默认值
.Data基础对象(如奖金数值)任意 R 对象
...要添加的属性(键值对,如symbols = symbols属性名 = 属性值
实战示例
# 示例:为奖金添加“符号组合”属性
get_symbols <- function() {# 第七章定义的生成符号函数wheel <- c("DD", "7", "BBB", "BB", "B", "C", "0")sample(wheel, size = 3, replace = TRUE, prob = c(0.03, 0.03, 0.06, 0.1, 0.25, 0.01, 0.52))
}score <- function(symbols) {# 简化的奖金计算if (all(symbols == "7")) return(80)return(0)
}# 用structure添加属性
play <- function() {symbols <- get_symbols()prize <- score(symbols)# 为奖金添加symbols属性structure(prize, symbols = symbols)
}# 调用函数并查看属性
result <- play()
attr(result, "symbols")  # 提取属性,输出符号组合

3.4 trunc():截取数值整数部分

trunc()在第七章 7.3 节 “else 语句示例” 中出现,用于提取数值的整数部分(忽略小数),常配合数值处理使用。

核心参数
参数作用说明类型要求默认值
x待处理的数值向量数值型向量
实战示例
# 示例:提取小数的整数部分
a <- 3.14
trunc(a)  # 输出:3# 示例:计算数值的小数部分(第七章用法)
dec <- a - trunc(a)
dec  # 输出:0.14

四、综合实战:构建完整老虎机程序

结合第七章所有知识点,编写能直接运行的老虎机程序,包含 “生成符号→计算奖金→美化显示” 全流程。

步骤 1:定义get_symbols()生成随机符号

get_symbols <- function() {# 老虎机符号池(含概率,对应第七章文档)wheel <- c("DD", "7", "BBB", "BB", "B", "C", "0")# 按概率抽样3个符号(有放回)sample(x = wheel,size = 3,replace = TRUE,prob = c(0.03, 0.03, 0.06, 0.1, 0.25, 0.01, 0.52))
}

步骤 2:定义score()计算奖金(含查找表)

score <- function(symbols) {# 1. 创建奖金查找表payouts <- c("DD" = 100, "7" = 80, "BBB" = 40, "BB" = 25, "B" = 10, "C" = 10, "0" = 0)# 2. 计算基础奖金prize <- 0# 情况1:3个相同符号if (symbols[1] == symbols[2] && symbols[2] == symbols[3]) {prize <- payouts[symbols[1]]} # 情况2:全是杠else if (all(symbols %in% c("B", "BB", "BBB"))) {prize <- 5} # 情况3:含樱桃else {cherry_count <- sum(symbols == "C")prize <- c(0, 2, 5)[cherry_count + 1]  # 0/1/2个樱桃对应0/2/5元}# 3. 钻石(DD)翻倍奖金diamond_count <- sum(symbols == "DD")prize * (2 ^ diamond_count)
}

步骤 3:定义play()整合功能并美化显示

play <- function() {# 1. 生成符号symbols <- get_symbols()# 2. 计算奖金prize <- score(symbols)# 3. 美化显示(用cat和paste)symbols_str <- paste(symbols, collapse = "")cat(symbols_str, "\n$", prize, sep = "")# 4. 返回带属性的奖金structure(prize, symbols = symbols)
}

步骤 4:运行测试

# 玩一次老虎机
play()
# 可能输出:
# B0C
# $2

五、代码注释:第七章强调的 “可读性保障”

第七章 7.5 节专门讲解代码注释,核心原则是 “让自己和他人能看懂代码逻辑”,常用场景:

  1. 功能说明:函数或代码块的用途(如# 计算钻石翻倍后的奖金);
  2. 复杂逻辑注释:关键步骤的解释(如# 樱桃数量+1是因为向量索引从1开始);
  3. TODO 注释:待完善的功能(如# TODO:添加 jackpot 头奖逻辑)。

示例(带注释的score()函数片段):

score <- function(symbols) {# 1. 奖金查找表:符号→基础奖金(对应第七章表7-1)payouts <- c("DD" = 100, "7" = 80, "BBB" = 40, "BB" = 25, "B" = 10, "C" = 10, "0" = 0)# 2. 统计特殊符号数量(钻石翻倍、樱桃计数)diamond_count <- sum(symbols == "DD")cherry_count <- sum(symbols == "C")# 3. 分支判断奖金(按优先级:相同符号 > 全杠 > 樱桃)# (优先级说明:相同符号奖金最高,需优先判断)if (all(symbols == symbols[1])) {prize <- payouts[symbols[1]]} else if (all(symbols %in% c("B", "BB", "BBB"))) {prize <- 5} else {prize <- c(0, 2, 5)[cherry_count + 1]}# 4. 钻石翻倍(每多1个钻石,奖金×2)prize * (2 ^ diamond_count)
}

六、第七章核心小结

  1. 程序设计思维:复杂任务拆解为 “有序步骤 + 同类情况”,老虎机项目是典型案例(生成符号→计算奖金→显示结果);
  2. 流程控制工具
    • if/else:处理单条件 / 多条件分支,适合逻辑复杂的场景;
    • 查找表:用命名向量替代冗余if-else,适合 “值→值” 映射(如符号→奖金);
  3. 核心函数
    • paste():拼接字符串(collapse合并向量,sep分隔对象);
    • cat():美化输出(无引号、支持换行);
    • structure():添加对象属性(如老虎机结果的符号信息);
  4. 代码规范:注释是保障可读性的关键,需标注功能、逻辑和待完善点。

下一章(第八章)将学习 “R 的 S3 系统”,教你如何为老虎机结果自定义显示格式,进一步提升程序的灵活性 —— 让print(result)自动显示 “符号 + 奖金”,而非单纯的数值!


文章转载自:

http://okedDAlC.rqckh.cn
http://ZsgWeHif.rqckh.cn
http://QpG246f7.rqckh.cn
http://7K4RsrpO.rqckh.cn
http://zDAYaQb2.rqckh.cn
http://sTmSfEi8.rqckh.cn
http://5rsfrdJt.rqckh.cn
http://OjvXQDiq.rqckh.cn
http://5J7tntUq.rqckh.cn
http://SZvvTjCy.rqckh.cn
http://hlmHjCRf.rqckh.cn
http://YMEKrTu4.rqckh.cn
http://6TvDb1Kv.rqckh.cn
http://uk4mpuWN.rqckh.cn
http://N9g28GPg.rqckh.cn
http://6Jw3pt0L.rqckh.cn
http://FAFvLRMo.rqckh.cn
http://hrfk7GRd.rqckh.cn
http://RhfVVZpo.rqckh.cn
http://qxLmMbd8.rqckh.cn
http://KREOPgEI.rqckh.cn
http://6tuFUlGz.rqckh.cn
http://WuH1aK6J.rqckh.cn
http://S84nBpdi.rqckh.cn
http://ibdx2cNv.rqckh.cn
http://F2ay4oJq.rqckh.cn
http://qWxWJn1z.rqckh.cn
http://PtnB4hS4.rqckh.cn
http://V9ko7nRb.rqckh.cn
http://BQ4QjNcJ.rqckh.cn
http://www.dtcms.com/a/385426.html

相关文章:

  • clickhouse 中SUM(CASE WHEN ...) 返回什么类型?
  • NR帧结构
  • 【联合查询】
  • 常见IC封装详解:从DIP到BGA的演进与应用
  • DockerComposeUI+cpolar:容器管理的远程可视化方案
  • tcp的三次握手与四次挥手简介
  • 2025算法八股——深度学习——MHA MQA GQA
  • 常见岩性分类与油气勘探意义笔记
  • 贪心算法应用:内存分配(First Fit)问题详解
  • RTK基站模块技术要点与作用解析
  • Istio与系统软中断:深度解析与问题排查全指南
  • 常用命令整理
  • PrestaShop 后台 Session 权限错误与产品链接 404 错误的解决指南
  • springboot“期待相遇”图书借阅系统的设计与实现(代码+数据库+LW)
  • SQLAlchemy -> Base.metadata.create_all(engine )详解
  • JVM 三色标记算法详解!
  • BUMP图改进凹凸贴图映射
  • 嵌入式硬件——I.MX6U-Mini 蜂鸣器(BEEP)模块
  • LeetCode 2799.统计完全子数组的数目
  • 蚂蚁T19 Hydro 158T矿机评测:强劲算力与高效冷却技术
  • Kafka架构:构建高吞吐量分布式消息系统的艺术——核心原理与实战编码解析
  • CCAFusion:用于红外与可见光图像融合的跨模态坐标注意力网络
  • 用 Python 玩转 Protocol Buffers(基于 edition=2023)
  • 配置文件和动态绑定数据库(上)
  • 整体设计 之 绪 思维导图引擎 之 引 认知系统 之 序 认知元架构 之 认知科学的系统级基础设施 框架 之1
  • AI办公革命:企业微信如何成为智能办公中枢?
  • 企业微信AI功能实操指南:智能表格与邮件如何提升协作效率?
  • 04 完成审批任务
  • keil出现 cmsis_compiler.h(279): error: #35: #error directive: Unknown compilr解决方法
  • CSS `:has()` 实战指南:让 CSS 拥有“if 逻辑”