首页 > 其他分享 >力扣题目解析--整数转罗马数

力扣题目解析--整数转罗马数

时间:2024-11-03 16:46:31浏览次数:4  
标签:std romanMap -- symbol value 力扣 num pair 解析

题目

七个不同的符号代表罗马数字,其值如下:

符号
I1
V5
X10
L50
C100
D500
M1000

罗马数字是通过添加从最高到最低的小数位值的转换而形成的。将小数位值转换为罗马数字有以下规则:

  • 如果该值不是以 4 或 9 开头,请选择可以从输入中减去的最大值的符号,将该符号附加到结果,减去其值,然后将其余部分转换为罗马数字。
  • 如果该值以 4 或 9 开头,使用 减法形式,表示从以下符号中减去一个符号,例如 4 是 5 (V) 减 1 (I): IV ,9 是 10 (X) 减 1 (I):IX。仅使用以下减法形式:4 (IV),9 (IX),40 (XL),90 (XC),400 (CD) 和 900 (CM)。
  • 只有 10 的次方(IXCM)最多可以连续附加 3 次以代表 10 的倍数。你不能多次附加 5 (V),50 (L) 或 500 (D)。如果需要将符号附加4次,请使用 减法形式

给定一个整数,将其转换为罗马数字。

示例 1:

输入:num = 3749

输出: "MMMDCCXLIX"

解释:

3000 = MMM 由于 1000 (M) + 1000 (M) + 1000 (M)
 700 = DCC 由于 500 (D) + 100 (C) + 100 (C)
  40 = XL 由于 50 (L) 减 10 (X)
   9 = IX 由于 10 (X) 减 1 (I)
注意:49 不是 50 (L) 减 1 (I) 因为转换是基于小数位

示例 2:

输入:num = 58

输出:"LVIII"

解释:

50 = L
 8 = VIII

示例 3:

输入:num = 1994

输出:"MCMXCIV"

解释:

1000 = M
 900 = CM
  90 = XC
   4 = IV

提示:

  • 1 <= num <= 3999

代码展示 

class Solution {
public:
    string intToRoman(int num) {
        std::vector<std::pair<int, std::string>> romanMap = {
            {1000, "M"}, {900, "CM"}, {500, "D"}, {400, "CD"},
            {100, "C"}, {90, "XC"}, {50, "L"}, {40, "XL"},
            {10, "X"}, {9, "IX"}, {5, "V"}, {4, "IV"}, {1, "I"}
        };

        std::string result = "";

        // 使用 while 循环处理整数
        while (num > 0) {
            for (const auto& [value, symbol] : romanMap) {
                if (num >= value) {
                    result += symbol;
                    num -= value;
                    break;
                }
            }
        }

        return result;
    
    }
};

代码逐行解释 

  1. 定义映射关系

    std::vector<std::pair<int, std::string>> romanMap = {
        {1000, "M"}, {900, "CM"}, {500, "D"}, {400, "CD"},
        {100, "C"}, {90, "XC"}, {50, "L"}, {40, "XL"},
        {10, "X"}, {9, "IX"}, {5, "V"}, {4, "IV"}, {1, "I"}
    };
    • 创建一个 vector,其中每个元素是一个 pair,第一个元素是整数值,第二个元素是对应的罗马数字字符串。
  2. 初始化结果字符串

    std::string result = "";
  3. 使用 while 循环处理整数

    while (num > 0) {
        for (const auto& [value, symbol] : romanMap) {
            if (num >= value) {
                result += symbol;
                num -= value;
                break;
            }
        }
    }
    • 使用 while 循环,只要 num 大于 0,就继续处理。
    • 内部使用 for 循环遍历 romanMap,找到第一个小于等于 num 的值。
    • 将对应的罗马数字字符串添加到 result 中。
    • 从 num 中减去对应的整数值。
    • 使用 break 跳出内层循环,继续处理下一个值。
for (const auto& [value, symbol] : romanMap) {
  1. for 循环

    • for 循环用于遍历 romanMap 中的每一个元素。
    • romanMap 是一个 std::vector<std::pair<int, std::string>> 类型的向量。
  2. const auto&

    • const auto& 是一种常用的语法,用于引用当前迭代的元素,避免不必要的复制。
    • const 表示我们不打算修改这些值。
    • auto 让编译器自动推导类型。
    • & 表示我们使用引用,而不是复制。
  3. 结构化绑定

    • [value, symbol] 是结构化绑定的语法。
    • value 和 symbol 分别绑定到 std::pair<int, std::string> 中的第一个和第二个元素。
    • value 绑定到 int 类型的值。
    • symbol 绑定到 std::string 类型的值。

等价的传统写法

如果你不熟悉结构化绑定,可以使用传统的写法来理解:

for (const auto& pair : romanMap) {
    int value = pair.first;
    std::string symbol = pair.second;
    if (num >= value) {
        result += symbol;
        num -= value;
        break;
    }
}

for (const auto& pair : romanMap)

  • for 循环:这是一个范围基的 for 循环,用于遍历 romanMap 中的每一个元素。
  • const auto&
    • const 表示我们不打算修改 pair
    • auto 让编译器自动推导 pair 的类型。
    • & 表示我们使用引用,而不是复制。这样可以提高性能,因为我们不需要每次都复制 pair

2. int value = pair.first;

  • pair.firstpair 是一个 std::pair<int, std::string> 类型的对象。
    • pair.first 是 pair 中的第一个元素,类型为 int
    • 我们将 pair.first 的值赋给 value 变量。

3. std::string symbol = pair.second;

  • pair.secondpair 是一个 std::pair<int, std::string> 类型的对象。
    • pair.second 是 pair 中的第二个元素,类型为 std::string
    • 我们将 pair.second 的值赋给 symbol 变量。

4. if (num >= value)

  • 条件判断:检查当前的 num 是否大于或等于 value
    • 如果 num 大于或等于 value,则进入 if 语句块。

5. result += symbol;

  • 字符串拼接:将 symbol 添加到 result 字符串的末尾。
    • result 是一个 std::string,用于存储最终的罗马数字字符串。

6. num -= value;

  • 减少 num:从 num 中减去 value
    • 这一步是为了处理剩下的部分,以便下一次循环继续处理剩余的值。

7. break;

  • 跳出循环:一旦找到一个匹配的罗马数字并处理完当前部分,跳出内层循环。
    • 这样可以确保每次只处理一个最大的匹配部分,然后继续处理剩余的部分。

 

 

标签:std,romanMap,--,symbol,value,力扣,num,pair,解析
From: https://blog.csdn.net/wxtg1921/article/details/143452065

相关文章

  • 封装红黑树实现mymap和myset
    前面我们已经了解过红黑树如何实现,和map与set的基本用法;要继续深入了解map,set中的库函数的用法,与细节那么我们就可以试着简单用语言封装模拟实现一下map与set; 这里就分享一下我的思路;若没了解过红黑树如何实现,和map与set的基本用法建议先去了解一下哦;我之前的文章中就有。......
  • java+vue计算机毕设电商小程序【开题+程序+论文+源码】
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展,电子商务已成为现代社会不可或缺的一部分。电商小程序作为移动端电商的一种新型形态,凭借其便捷性、即时性和轻量化的特点,迅......
  • java+vue计算机毕设大学校园后勤移动报修系统【开题+程序+论文+源码】
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着信息技术的飞速发展和智能手机的普及,移动应用已成为人们日常生活和工作中的重要组成部分。在大学校园环境中,后勤管理作为保障教学与生活秩序的关......
  • FastAPI 路径参数详解:动态路径与数据校验的灵活实现
    FastAPI路径参数详解:动态路径与数据校验的灵活实现本文全面介绍了在FastAPI中使用路径参数的技巧和实现方式。路径参数允许API动态响应不同路径中的请求信息,结合URL(UniformResourceLocator)和URI(UniformResourceIdentifier)进行资源定位和标识。URL是指资源的完......
  • C++——二叉树(进阶)
    1.二叉搜索树1.1概念二叉搜索树又称二叉排序树,它或是一棵空树,又或是具有以下性质的二叉树:若它的左子树不为空,则左子树上所有节点的值都小于根节点的值若它的右子树不为空,则右子树上所有节点的值都大于根节点的值它的左右子树也分别为二......
  • 差速AGV机器人速度控制【径向速度控制】【横向速度控制】【速度耦合】
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、径向速度控制1.s曲线速度规划2.位置偏差的约束3.贝塞尔速度约束(起始段和末端)4.其他工况限速(避障,急停等)二、横向速度控制(MPC)1.建立系统模型2.定义目标函数3.约束条件4.求解优化问题5.将控......
  • K-th 问题的一般思路
    是在同一个情景下,求出前\(K\)类最小的方案价值。其可以等效转化为:将每一种方案视作一个状态,并通过状态之间的大小关系连边(严格),我们求出其拓扑序的前\(k\)个节点。笔者认为,所有的优化方案本质上都是在尽可能少的边数下保留这个拓扑结构,亦或者是利用隐式建图等技巧(因为事实......
  • java全栈day07-后端Web基础-Maven基础
    一、什么是MavenMaven是一款用于管理和构建Java项目的工具。作用:(提供jar包,跨平台,不同软件使用(IDEA、Eclipse等))导入jar包方式不同简单来说:(1)方便的依赖管理(2)统一的项目结构(3)标准的项目构建流程二、IDEA集成Maven首先需要配置Maven环境(全局)再创建项目(......
  • 0-ARM Linux驱动开发-字符设备
    0-ARMLinux驱动开发-字符设备一、字符设备概述Linux系统中,设备被分为字符设备、块设备和网络设备等。字符设备以字节流的方式进行数据传输,数据的访问是按顺序的,一个字节一个字节地进行读取和写入操作,没有缓冲区。例如,终端(/dev/tty)、鼠标、键盘等设备都是典型的字符设备......