C++笔记之表驱动法

news2024/11/27 23:44:07

C++笔记之表驱动法

code review!
在这里插入图片描述

文章目录

  • C++笔记之表驱动法
    • 0.数组小技巧
    • 1.std::map实现
    • 2.结构体实现
    • 3.数组和结构体结合实现表驱动法-存储函数指针
    • 4.表驱动法概念-ChatGPT
    • 5. 直接访问表(Direct Access Table)的示例
    • 6. 索引访问表(Indexed Access Table)的示例
    • 7. 阶梯访问表(Look-Up Table)的示例
    • 8.《代码大全(第二版)》——表驱动法
    • 表驱动法经典应用:作为状态转移数组

参考博文:

一个计算器的程序—表驱动法

0.数组小技巧

在这里插入图片描述

代码

int monthDays[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int getDays(int month){
    return monthDays[--month];
}

1.std::map实现

在这里插入图片描述

代码

#include <iostream>
#include <map>

// 定义一个映射表,将输入值映射到输出值
std::map<int, std::string> table = {
    {1, "One"},
    {2, "Two"},
    {3, "Three"},
    {4, "Four"},
    {5, "Five"}
};

int main() {
    int input;
    std::cout << "请输入一个数字 (1-5): ";
    std::cin >> input;

    // 使用映射表查找输入值对应的输出值
    auto it = table.find(input);
    if (it != table.end()) {
        std::cout << "对应的字符串为: " << it->second << std::endl;
    } else {
        std::cout << "找不到对应的字符串" << std::endl;
    }

    return 0;
}

2.结构体实现

在这里插入图片描述

代码

#include <iostream>
#include <vector>

// 定义一个结构体,包含输入和输出字段
struct Mapping {
    int input;
    std::string output;
};

// 定义一个表格,将输入值映射到输出值
std::vector<Mapping> table = {
    {1, "One"},
    {2, "Two"},
    {3, "Three"},
    {4, "Four"},
    {5, "Five"}
};

int main() {
    int input;
    std::cout << "请输入一个数字 (1-5): ";
    std::cin >> input;

    // 使用表格查找输入值对应的输出值
    for (const Mapping& entry : table) {
        if (entry.input == input) {
            std::cout << "对应的字符串为: " << entry.output << std::endl;
            return 0; // 找到匹配项后退出
        }
    }

    std::cout << "找不到对应的字符串" << std::endl;

    return 0;
}

3.数组和结构体结合实现表驱动法-存储函数指针

在这里插入图片描述

运行
在这里插入图片描述

代码

#include <iostream>
#include <functional>

// 定义一个结构体来存储操作符和对应的函数指针
struct Operator {
    char op;
    std::function<double(double, double)> func;
};

// 定义一些操作函数
double Add(double a, double b) {
    return a + b;
}

double Subtract(double a, double b) {
    return a - b;
}

double Multiply(double a, double b) {
    return a * b;
}

double Divide(double a, double b) {
    if (b != 0) {
        return a / b;
    } else {
        std::cerr << "Error: Division by zero" << std::endl;
        return 0.0;
    }
}

int main() {
    // 创建操作符数组
    Operator operators[] = {
        {'+', Add},
        {'-', Subtract},
        {'*', Multiply},
        {'/', Divide}
    };

    char userOperator;
    double operand1, operand2;

    std::cout << "Enter an operator (+, -, *, /): ";
    std::cin >> userOperator;

    // 查找用户输入的操作符,并执行相应的函数
    for (const Operator& op : operators) {
        if (op.op == userOperator) {
            std::cout << "Enter two operands: ";
            std::cin >> operand1 >> operand2;
            double result = op.func(operand1, operand2);
            std::cout << "Result: " << result << std::endl;
            break;
        }
    }

    return 0;
}

4.表驱动法概念-ChatGPT

表驱动法是一种编程技巧,用于将输入值与输出值之间的关系存储在数据结构中,以减少大量的条件语句或计算逻辑。表驱动法可以采用不同的实现方式,包括直接访问表、索引访问表和阶梯访问表。

  1. 直接访问表(Direct Access Table):
    直接访问表是最简单的表,其中每个输入对应一个唯一的输出。这通常用于快速查找信息,例如字典或电话簿。以下是一个示例,显示如何通过人名查找其电话号码:

    直接访问表(姓名对应电话号码):
    -----------------------------------------
    | 姓名     | 电话号码          |
    -----------------------------------------
    | 小明     | 123-456-7890    |
    | 小红     | 234-567-8901    |
    | 小李     | 345-678-9012    |
    | ...     | ...             |
    -----------------------------------------
    
  2. 索引访问表(Indexed Access Table):
    索引访问表使用一个索引来引导到正确的数据记录。索引通常是关键字或标识符,它们指向数据表的特定行。以下是一个示例,显示如何通过学生ID查找学生信息:

    索引访问表(学生ID对应学生信息):
    ----------------------------------------------
    | 学生ID  | 姓名      | 年龄 | 课程   |
    ----------------------------------------------
    | 1001    | 小明      | 18   | 数学   |
    | 1002    | 小红      | 19   | 英语   |
    | 1003    | 小李      | 20   | 物理   |
    | ...     | ...       | ...  | ...    |
    ----------------------------------------------
    
  3. 阶梯访问表(LUT - Look-Up Table):
    阶梯访问表包含多个级别的数据,通常按照某种特定的条件进行分组。查找数据需要根据条件跳转到正确的级别,然后在该级别中查找所需信息。以下是一个示例,显示如何通过年龄范围查找不同年龄组的人数:

    阶梯访问表(年龄范围对应人数):
    ----------------------------------------------
    | 年龄范围  | 人数     |
    ----------------------------------------------
    | 0-10岁   | 100     |
    | 11-20岁  | 200     |
    | 21-30岁  | 150     |
    | ...      | ...     |
    ----------------------------------------------
    

这些示例展示了不同类型的表驱动法,它们在不同的应用中有不同的用途。直接访问表用于单一映射关系,索引访问表用于标识符到数据的映射,而阶梯访问表用于范围或条件相关的数据检索。以下是这些不同实现方式的详细解释:

  1. 直接访问表(Direct Lookup Table):

    • 直接访问表是一种最简单的表驱动法实现方式。
    • 在直接访问表中,输入值(通常作为键)与对应的输出值直接存储在一个数据结构中,通常是数组或散列表(哈希表)。
    • 通过直接查找输入值,你可以立即找到对应的输出值,而无需进行复杂的计算或搜索。
    • 这种方式适用于输入值的范围有限且已知的情况,例如将字母映射到其ASCII码值的情况。
  2. 索引访问表(Indexed Lookup Table):

    • 索引访问表是一种使用索引(通常是整数)来查找输出值的表驱动法实现方式。
    • 输入值与索引之间建立了一对一或一对多的映射关系,这个索引用于在表中查找对应的输出值。
    • 通常,表会以数组或向量的形式存储,索引用作数组的索引,从而找到输出值。
    • 这种方式适用于输入值不需要连续的情况,例如在游戏编程中,将不同类型的敌人映射到其属性和行为的情况。
  3. 阶梯访问表(Stepwise Lookup Table):

    • 阶梯访问表是一种将输入值划分为范围或阶段,并为每个范围分配一个输出值的表驱动法实现方式。
    • 输入值被划分为离散的阶梯(也称为阶段或区间),然后为每个阶梯分配一个输出值。
    • 输入值根据其所属的阶梯来查找对应的输出值,通常使用条件语句或查找表来实现。
    • 这种方式适用于将连续的输入值映射到离散的输出值范围,例如在温度范围内确定天气状况的情况,将分数映射到等级的情况等。

5. 直接访问表(Direct Access Table)的示例

#include <iostream>
#include <map>
#include <string>

int main() {
    // 创建并初始化直接访问表(姓名对应电话号码)
    std::map<std::string, std::string> directAccessTable = {
        {"小明", "123-456-7890"},
        {"小红", "234-567-8901"},
        {"小李", "345-678-9012"}
    };

    // 通过姓名查找电话号码
    std::string name = "小明";
    if (directAccessTable.find(name) != directAccessTable.end()) {
        std::cout << name << "的电话号码是:" << directAccessTable[name] << std::endl;
    } else {
        std::cout << "找不到姓名为" << name << "的记录。" << std::endl;
    }

    return 0;
}

6. 索引访问表(Indexed Access Table)的示例

#include <iostream>
#include <map>
#include <string>

int main() {
    // 创建并初始化索引访问表(学生ID对应学生信息)
    std::map<int, std::map<std::string, std::string>> indexedAccessTable = {
        {1001, {{"姓名", "小明"}, {"年龄", "18"}, {"课程", "数学"}}},
        {1002, {{"姓名", "小红"}, {"年龄", "19"}, {"课程", "英语"}}},
        {1003, {{"姓名", "小李"}, {"年龄", "20"}, {"课程", "物理"}}}
    };

    // 通过学生ID查找学生信息
    int studentId = 1001;
    if (indexedAccessTable.find(studentId) != indexedAccessTable.end()) {
        std::cout << "学生ID为" << studentId << "的学生信息:" << std::endl;
        for (const auto& pair : indexedAccessTable[studentId]) {
            std::cout << pair.first << ": " << pair.second << std::endl;
        }
    } else {
        std::cout << "找不到学生ID为" << studentId << "的学生记录。" << std::endl;
    }

    return 0;
}

7. 阶梯访问表(Look-Up Table)的示例

#include <iostream>
#include <map>
#include <string>

int main() {
    // 创建并初始化阶梯访问表(年龄范围对应人数)
    std::map<std::string, int> lookupTable = {
        {"0-10岁", 100},
        {"11-20岁", 200},
        {"21-30岁", 150}
    };

    // 通过年龄范围查找人数
    std::string ageRange = "11-20岁";
    if (lookupTable.find(ageRange) != lookupTable.end()) {
        std::cout << ageRange << "的人数为:" << lookupTable[ageRange] << std::endl;
    } else {
        std::cout << "找不到" << ageRange << "的人数记录。" << std::endl;
    }

    return 0;
}

在这里插入图片描述

8.《代码大全(第二版)》——表驱动法

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

表驱动法经典应用:作为状态转移数组

表驱动最常见在状态机设计模式里作为状态转移数组,在命令设计模式里作为命令码数组。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1175216.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么情况造成互斥锁死锁

由于互斥锁的使用不当&#xff0c;导致多个线程无法进行下一步的代码运行&#xff0c;也就是说竞争锁的两个线程互相锁住&#xff0c;导致整个进程无法往下运行。 举个例子&#xff1a; 两个锁&#xff0c;两个线程&#xff0c;两个线程运行的条件都是需要同时获得这两把锁&a…

Canvas 梦幻树生长动画

canvas可以制作出非常炫酷的动画&#xff0c;以下是一个梦幻树的示例。 效果图 源代码 <!DOCTYPE> <html> <head> <meta http-equiv"Content-Type" content"text/html; charsetutf-8" /> <title>梦幻数生长动画</title&…

Python基础入门例程49-NP49 字符列表的长度

最近的博文&#xff1a; Python基础入门例程48-NP48 验证登录名与密码&#xff08;条件语句&#xff09;-CSDN博客 Python基础入门例程47-NP47 牛牛的绩点&#xff08;条件语句&#xff09;-CSDN博客 Python基础入门例程46-NP46 菜品的价格&#xff08;条件语句&#xff09;…

python栈_简单算术表达式_加减乘除

# 从左到右遍历中缀表达式中的每个数字和符号&#xff0c;若是数字就输出&#xff0c;即成为后缀表达式的一部分&#xff1b;若是符号则要分为两种情况&#xff1a; # (1)是括号时&#xff0c;如果是左括号&#xff0c;直接将左括号入栈&#xff0c;如果是右括号则栈顶元素依次…

P37~41 第九章 正弦稳态电路的分析

本章我们重点分析当正弦作为激励&#xff0c;作用在电路在上&#xff0c;经过很短时间内到达稳态之后电路的一些特征。 1、阻抗和导纳对偶 1.1阻抗 1.2RLC串联 以不变的向量为参考向量 电阻只由元件自身决定&#xff0c;阻抗由元件和激励的脚频率决定。 1.3导纳 1.4RLC并…

HTML_案例1_注册页面

用纯html页面&#xff0c;不用css画一个注册页面。 最终效果如下&#xff1a; html页面代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>注册页面</title> </head>…

二、Hadoop分布式系统基础架构

1、分布式 分布式体系中&#xff0c;会存在众多服务器&#xff0c;会造成混乱等情况。那如何让众多服务器一起工作&#xff0c;高效且不出现问题呢&#xff1f; 2、调度 &#xff08;1&#xff09;架构 在大数据体系中&#xff0c;分布式的调度主要有2类架构模式&#xff1a…

基于晶体结构算法的无人机航迹规划-附代码

基于晶体结构算法的无人机航迹规划 文章目录 基于晶体结构算法的无人机航迹规划1.晶体结构搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用晶体结构算法来优化无人机航迹规划。 …

【C语法学习】17 - fwrite()函数

文章目录 1 函数原型2 参数3 返回值4 示例 1 函数原型 fwrite()&#xff1a;将ptr指向的内存空间中储存的数据块写入与指定流stream相关联的二进制文件中&#xff0c;函数原型如下&#xff1a; size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream)2 参…

SQL 左连接 LEFT JOIN 关键字||SQL右连接 RIGHT JOIN 关键字

SQL 左连接 LEFT JOIN 关键字 SQL左链接LEFT JOIN关键字返回左表&#xff08;表1&#xff09;中的所有行&#xff0c;即使在右表&#xff08;表2&#xff09;中没有匹配。如果在正确的表中没有匹配&#xff0c;结果是NULL。 SQL LEFT JOIN 语法 SELECT column_name(s) …

环形链表和相交链表OJ题

环形链表和相交链表OJ题 这篇博客详细讲解了环形数组和相交数组的问题 文章目录 环形链表和相交链表OJ题一、环形链表e.g.1e.g.2 二、相交链表 一、环形链表 环形列表是指尾结点next不指向NULL了&#xff0c;而是指向包括自己的前面任意一个结点。 e.g.1 题目及要求&#xf…

❤️ React的安装和使用(实战篇)

React的安装和使用 一、React的安装和使用 reactJs警告提示&#xff1a; This version of tar is no longer supported, and will not receive security updates. Please upgrade asap 翻译&#xff1a;tar2.2.2&#xff1a;此版本的tar不再受支持&#xff0c;将不会收到安全…

SwiftUI Swift 多个 sheet

今天做一个多个 sheet 的效果&#xff0c;点击下面三个按钮打开不同的 sheet 。 Show me the code import SwiftUIenum CurrentActiveSheet: Identifiable {case add, edit, deletevar id: Int {hashValue} }struct MoreSheet: View {State var currentActiveSheet: CurrentAc…

拓扑排序(Java实现)

一、基本思想 拓扑排序是一种对有向无环图&#xff08;DAG&#xff09;进行排序的算法&#xff0c;它将所有顶点排成一个线性序列&#xff0c;使得对于任意一条有向边&#xff08;u, v&#xff09;&#xff0c;u在序列中都出现在v之前。拓扑排序的思想非常直观&#xff0c;就像…

已完结,给小白的《50讲Python自动化办公》

大家好&#xff0c;这里是程序员晚枫&#xff0c;小红薯也叫这个名。 写在前面 上个周末去成都参加了第8届中国开源年会&#xff0c;认识了很多行业前辈和优秀的同龄人。 我发现在工作之外还能有一番事业的人&#xff0c;都有一个让我羡慕的共同点&#xff1a;有一个拿得出手…

Redis实战 | 使用Redis 的有序集合(Sorted Set)实现排行榜功能,和Spring Boot集成

专栏集锦&#xff0c;大佬们可以收藏以备不时之需 Spring Cloud实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9270827.html Python 实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9271194.html Logback 详解专栏&#xff1a;https:/…

LangChain+LLM实战---ChatGPT的工作原理

一个词一个词的输出 ChatGPT能够自动生成类似于人类书写的文本&#xff0c;这是非常了不起和出乎意料的。但它是如何做到的&#xff1f;为什么会有效果呢&#xff1f;我的目的在于大致概述ChatGPT内部发生了什么&#xff0c;然后探讨它为什么能够很好地生成我们认为有意义的文…

[MRCTF2020]你传你呢1

提示 只对php以及phtml文件之类的做了防护content-type.htaccess文件 这里就不整那么麻烦直接抓包测试 首先对后缀测试看过滤了哪些 (php php3 pht php5 phtml phps) 全部被ban了 到这里的后续思路通过上传一些配置文件把上传的图片都以php文件执行 尝试上传图片码, 直接上传成…

[自动化运维工具] Ansible的简单介绍与常用模块详解

文章目录 1. Ansible概述1.1 简介1.2 Ansible的特性1.3 Ansible的组件构成1.4 Ansible的工作原理 2. Ansible环境部署2.1 前置准备2.2 安装ansible2.3 查看基本信息2.4 配置远程主机清单 3. Ansible的常用模块3.1 ansible的基础命令格式3.2 Command模块3.2.1 基本格式和常用参数…

Android 10.0 系统wifi列表显示已连接但无法访问网络问题解决

1.前言 在10.0的系统产品开发中,在wifi模块也很重要,但是在某些情况下对于一些wifi连接成功后,确显示已连接成功,但是无法访问互联网 的情况,所以实际上这时可以正常上网的,就是显示的不正常,所以就需要分析连接流程然后解决问题 如图所示 2.系统wifi列表显示已连接但无…