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

题目

罗马数字包含以下七种字符: I, V, X, LCD 和 M

字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

例如, 罗马数字 2 写做 II ,即为两个并列的 1 。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

  • I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
  • X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 
  • C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。

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

示例 1:

输入: s = "III"
输出: 3

示例 2:

输入: s = "IV"
输出: 4

示例 3:

输入: s = "IX"
输出: 9

示例 4:

输入: s = "LVIII"
输出: 58
解释: L = 50, V= 5, III = 3.

示例 5:

输入: s = "MCMXCIV"
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.

提示:

  • 1 <= s.length <= 15
  • s 仅含字符 ('I', 'V', 'X', 'L', 'C', 'D', 'M')
  • 题目数据保证 s 是一个有效的罗马数字,且表示整数在范围 [1, 3999] 内
  • 题目所给测试用例皆符合罗马数字书写规则,不会出现跨位等情况。
  • IL 和 IM 这样的例子并不符合题目要求,49 应该写作 XLIX,999 应该写作 CMXCIX 。
  • 关于罗马数字的详尽书写规则,可以参考 罗马数字 - 百度百科。

代码展示 

#include <unordered_map>
#include<string>
using namespace std;
class Solution {
public:int romanToInt(string s) {std::unordered_map<char, int> romanMap = {{'I', 1}, {'V', 5}, {'X', 10}, {'L', 50},{'C', 100}, {'D', 500}, {'M', 1000}};int sum=0;int ret=s.size();for (size_t i = 0; i <ret ; ++i) {int currentValue = getIntegerValue(s[i], romanMap);if (i + 1 < s.length()) {int nextValue = getIntegerValue(s[i + 1], romanMap);if (currentValue < nextValue) {sum += nextValue - currentValue;++i; // 跳过下一个字符} else {sum += currentValue;}} else {sum += currentValue;}}return sum;}private:int getIntegerValue(char romanchar,const unordered_map<char, int>&map){auto it=map.find(romanchar);if(it!=map.end()){return it->second;}else{return 0;}
}};

代码解释 

  1. romanToInt 方法

    • std::unordered_map<char, int> romanMap:创建一个无序映射表,存储罗马数字字符及其对应的整数值。
    • int sum = 0:初始化总和为0。
    • int ret = s.size():获取输入字符串的长度。
    • for (size_t i = 0; i < ret; ++i):遍历字符串中的每一个字符。
    • int currentValue = getIntegerValue(s[i], romanMap):获取当前字符对应的整数值。
    • if (i + 1 < s.length()):检查是否还有下一个字符。
    • int nextValue = getIntegerValue(s[i + 1], romanMap):获取下一个字符对应的整数值。
    • if (currentValue < nextValue):如果当前字符的值小于下一个字符的值,说明这是一个减法情况。
    • sum += nextValue - currentValue:计算减法结果并添加到总和中。
    • ++i:跳过下一个字符。
    • else:否则,直接加上当前字符的值。
    • else:如果已经是最后一个字符,直接加上其值。
    • return sum:返回计算结果。
  2. getIntegerValue 方法

    • auto it = map.find(romanchar):在映射表中查找给定字符。
    • if (it != map.end()):如果找到了对应的值,返回该值。
    • else:如果没有找到对应的值,返回0。

   3. 辅助函数 getIntegerValue

int getIntegerValue(char romanChar, const std::unordered_map<char, int>& map) {auto it = map.find(romanChar);if (it != map.end()) {return it->second;}return 0; // 如果找不到,返回 0
}

详细解释

  1. 函数签名

    int getIntegerValue(char romanChar, const std::unordered_map<char, int>& map)
    • int getIntegerValue:函数返回一个整数值。
    • char romanChar:函数接受一个字符参数,表示罗马数字字符。
    • const std::unordered_map<char, int>& map:函数接受一个常量引用参数,表示映射表。std::unordered_map<char, int> 是一个哈希表,键是字符,值是整数。
  2. 查找字符

    auto it = map.find(romanChar);
    • map.find(romanChar):在映射表 map 中查找键为 romanChar 的元素。
    • auto it:使用 auto 关键字自动推导 it 的类型。it 是一个迭代器,指向找到的元素。
  3. 检查是否找到

    if (it != map.end()) {return it->second;
    }
    • if (it != map.end()):检查迭代器 it 是否不等于 map.end()map.end() 是一个特殊迭代器,表示映射表的结束位置。
    • 如果 it 不等于 map.end(),说明找到了键为 romanChar 的元素。
    • return it->second:返回找到的元素的值。it->second 表示迭代器 it 指向的键值对中的值。
  4. 未找到时返回 0

    return 0; // 如果找不到,返回 0
    • 如果 it 等于 map.end(),说明没有找到键为 romanChar 的元素。
    • 返回 0,表示未找到对应的整数值。

示例解释

假设我们有一个映射表 romanMap

std::unordered_map<char, int> romanMap = {{'I', 1}, {'V', 5}, {'X', 10}, {'L', 50}, {'C', 100}, {'D', 500}, {'M', 1000}
};
示例调用
  1. 调用 getIntegerValue('I', romanMap)

    • map.find('I') 返回一个迭代器,指向键为 'I' 的元素。
    • it->second 是 1。
    • 返回 1。
  2. 调用 getIntegerValue('V', romanMap)

    • map.find('V') 返回一个迭代器,指向键为 'V' 的元素。
    • it->second 是 5。
    • 返回 5。
  3. 调用 getIntegerValue('Z', romanMap)

    • map.find('Z') 返回 map.end(),因为 'Z' 不在映射表中。
    • 返回 0。

4.auto it 和迭代器的具体使用方法

迭代器的概念

在 C++ 中,迭代器是一种通用的概念,用于遍历容器中的元素。迭代器的行为类似于指针,可以用来访问和操作容器中的元素。不同的容器(如 std::vectorstd::liststd::unordered_map 等)有不同的迭代器类型。

std::unordered_map 的迭代器

std::unordered_map 是一个哈希表,它的迭代器类型是 std::unordered_map<K, V>::iteratorstd::unordered_map<K, V>::const_iterator,具体取决于你是否需要修改映射表中的元素。

迭代器的成员
  • it->first:访问键(key)。
  • it->second:访问值(value)。

auto 关键字

auto 关键字用于自动推导变量的类型。在 auto it = map.find(romanChar); 中,编译器会根据 map.find(romanChar) 的返回类型自动推导 it 的类型。在这种情况下,it 的类型是 std::unordered_map<char, int>::iterator

使用迭代器的注意事项

  1. 检查迭代器的有效性

    • 在使用迭代器之前,必须确保它有效。通常通过检查迭代器是否等于 map.end() 来判断是否找到了元素。
    • 示例:
      auto it = map.find(romanChar);
      if (it != map.end()) {// 找到了元素
      } else {// 没有找到元素
      }
  2. 避免越界

    • 不要试图访问超出容器范围的元素。例如,不要在迭代器等于 map.end() 时访问 it->second
    • 示例:
      auto it = map.find(romanChar);
      if (it != map.end()) {int value = it->second; // 安全访问
      }
  3. 修改元素

    • 如果你使用的是非常量迭代器(std::unordered_map<K, V>::iterator),可以通过迭代器修改值。
    • 示例:
      auto it = map.find(romanChar);
      if (it != map.end()) {it->second = 10; // 修改值
      }
  4. 迭代器失效

    • 在某些操作(如插入、删除)之后,迭代器可能会失效。使用迭代器时要确保它仍然有效。
    • 示例:
      auto it = map.find(romanChar);
      if (it != map.end()) {int value = it->second;// 插入新元素后,it 仍然有效map.insert({'A', 1});// 删除元素后,it 可能失效map.erase(romanChar);
      }

 

总结 

其实罗马数字转换为整型这个问题并没有这样复杂,只是我在做题目的过程中想要利用一下函数和使用一下自定义的函数,才会显得这个代码有些臃肿和复杂。我最初的想法就是通过映射表来处理罗马数字和整数之间的关系,只是在推进的过程之中。我发现要解决这个问题就需要自定义一个函数去专门的在映射表之中寻找罗马数字和整型数字,因此就定义了一个这样的函数去通过罗马数字寻找整数,而在我已经完成这个函数,并且。得到结果的时候我发现罗马数字有一个很关键的问题就是。数字小的时候,有可能会把数字大的放在后头,类似于罗马数字四-----IV,这样子就不能只通过直接读取字符串来简单地进行加得到整数。如果没有这样的特性,我认为映射表应该是更简单的。但是正是因为这样的特性造成了原本优秀的想法反倒吃了瘪,进而造成了代码的臃肿。

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

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

相关文章

Pinia-状态管理

Pinia-状态管理 特点&#xff1a; 1. 轻量和模块化 Pinia 是一个轻量级的状态管理库&#xff0c;支持模块化管理&#xff0c;即可以将应用的状态分成多个 store 以实现更好的组织。使用 Pinia&#xff0c;可以定义多个 store&#xff0c;每个 store 都是一个独立的模块&#x…

openpnp - 在openpnp中单独测试相机

文章目录 openpnp - 在openpnp中单独测试相机概述笔记测试工装相机镜头顶部盖子到目标的距离END openpnp - 在openpnp中单独测试相机 概述 底部相机的位置不合适, 重新做了零件&#xff0c;准备先确定一下相机和吸嘴的距离是多少才合适。 如果在设备上直接实验&#xff0c;那…

网络模型——二层转发原理

网课地址&#xff1a;网络模型_二层转发原理&#xff08;三&#xff09;_哔哩哔哩_bilibili 一、路由交换 网络&#xff1a;用来信息通信&#xff0c;信息共享的平台。 网络节点&#xff08;交换机&#xff0c;路由器&#xff0c;防火墙&#xff0c;AP&#xff09;介质&#…

[watevrCTF 2019]Voting Machine 1-好久不见10

shiiftF12查找字符串&#xff0c;发现flag.text跟踪 from pwn import * i remote("node5.anna.nssctf.cn",22956) address 0x400807 payload ba*(0x28) p64(address) i.sendline(payload) i.interactive()

【Linux】从零开始使用多路转接IO --- select

碌碌无为&#xff0c;则余生太长&#xff1b; 欲有所为&#xff0c;则人生苦短。 --- 中岛敦 《山月记》--- 从零开始认识五种IO模型 1 前言2 认识多路转接select3 多路转接select等待连接4 完善代码5 总结 1 前言 上一篇文章我们讲解了五种IO模型的基本概念&#xff0c;并…

【Java SE 】String 类 详解!

&#x1f525;博客主页&#x1f525;&#xff1a;【 坊钰_CSDN博客 】 欢迎各位点赞&#x1f44d;评论✍收藏⭐ 1. String 的地位 在Java 编程中&#xff0c;字符串的使用是非常频繁的&#xff0c;而字符串的使用有离不开 String类 &#xff0c;在开发和面试中String类也是非常…

专业130+总400+武汉理工大学855信号与系统考研经验电子信息与通信工程,真题,大纲,参考书。

已经顺利读研一段时间&#xff0c;回顾一下考研还是历历在目。应群里学弟要求&#xff0c;回忆总结一下自己考研经历&#xff0c;希望对大家复习有帮助。总分400&#xff0c;专业课855信号与系统130&#xff08;犯了低级错误&#xff0c;计算出现问题&#xff0c;大家专业好好准…

Self-Lengthen:阿里千问开源提升 LLM 长文本生成能力的训练框架

❤️ 如果你也关注大模型与 AI 的发展现状&#xff0c;且对大模型应用开发非常感兴趣&#xff0c;我会快速跟你分享最新的感兴趣的 AI 应用和热点信息&#xff0c;也会不定期分享自己的想法和开源实例&#xff0c;欢迎关注我哦&#xff01; &#x1f966; 微信公众号&#xff…

双向链表及如何使用GLib的GList实现双向链表

双向链表是一种比单向链表更为灵活的数据结构&#xff0c;与单向链表相比可以有更多的应用场景&#xff0c;本文讨论双向链表的基本概念及实现方法&#xff0c;并着重介绍使用GLib的GList实现单向链表的方法及步骤&#xff0c;本文给出了多个实际范例源代码&#xff0c;旨在帮助…

C++笔试题之实现一个定时器

一.定时器&#xff08;timer&#xff09;的需求 1.执行定时任务的时&#xff0c;主线程不阻塞&#xff0c;所以timer必须至少持有一个线程用于执行定时任务 2.考虑到timer线程资源的合理利用&#xff0c;一个timer需要能够管理多个定时任务&#xff0c;所以timer要支持增删任务…

【Java笔记】1-JDK/JRE/JVM是个啥?

JDK、JRE、JVM可以说是入门必须了解的三个词汇 先说全称 JDK&#xff1a;Java Development Kit&#xff0c;Java开发工具包 JRE&#xff1a;Java Runtime Environment&#xff0c;Java运行环境 JVM&#xff1a;Java Virtual Machine&#xff0c;Java虚拟机 再说关系 JVM⊆J…

c语言-进位计数制

文章目录 一、进位计数制是什么&#xff1f;二、c语言1.二进制转十进制2.十进制转二进制 一、进位计数制是什么&#xff1f; 进位计数制简称进制&#xff0c;是人类用于计算数量的基本规则。 可使用数字符号的数目称为基数或底数&#xff0c;基数个数为n个&#xff0c;即可称n…

HTML 基础标签——结构化标签<html>、<head>、<body>

文章目录 1. <html> 标签2. <head> 标签3. <body> 标签4. <div> 标签5. <span> 标签小结 在 HTML 文档中&#xff0c;使用特定的结构标签可以有效地组织和管理网页内容。这些标签不仅有助于浏览器正确解析和渲染页面&#xff0c;还能提高网页的可…

【算法赌场】区间合并

区间问题 区间问题的引入 数学上&#xff0c;用两个数字可以确定数轴上的一个区间&#xff0c;较小的数字叫做区间的左端点&#xff0c;也叫区间起点&#xff0c;较大的数字叫做区间的右端点&#xff0c;也叫区间终点。 在算法竞赛中&#xff0c;很多题目是以区间为单位去进行…

给定开始日期时间结束日期时间、间隔得到符合条件的序列pandas.timedelta_range()

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 给定开始日期时间 结束日期时间、间隔 得到符合条件的序列 pandas.timedelta_range() [太阳]选择题 以下代码执行后&#xff0c;delta中包含的时间差序列的个数是多少&#xff1f; import pa…

【AI工作流】FastGPT - 深入解析FastGPT工作流编排:从基础到高级应用的全面指南

文章目录 一、工作流编排概述二、FastGPT的节点类型1. 基础功能插件(1) 文本输出(2) 功能调用(3) 工具(4) 外部调用(5) 其他 2. 系统插件3. 团队插件 三、工作流中的流向结语 在当今快速发展的人工智能领域&#xff0c;工作流编排的能力已成为提升用户体验和应用效率的关键因素…

qt QAction详解

1、概述 QAction是Qt框架中的一个抽象类&#xff0c;用于表示用户界面中的一个动作&#xff08;action&#xff09;。这些动作可以绑定到菜单项、工具栏按钮或快捷键上&#xff0c;提供了一种灵活的方式来处理用户交互。QAction不仅包含了动作的名称、图标、提示信息等属性&am…

MRCTF2020:你传你ma呢

文件上传题先判断黑白名单过滤&#xff0c;先传个最简单的木马 这里上传不了php文件&#xff0c;猜测可能是对php文件进行了过滤&#xff0c;将文件改为任意后缀这里改为.abc 还是上传不成功&#xff0c;猜测可能对MIME也做了过滤&#xff0c;将Content-Type更改为image/jpeg再…

LeetCode (206单链表反转)

目录 题目描述: 代码: 第一种: 第二种: 第三种: 第四种: 第五种: 主函数: ListNode类: 题目描述: 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3…

C# Modbus RTU通讯回顾

涉及技术&#xff1a; 1.使用NMdbus4 库 2.ushort[]转int 记得之前刚学习的时候&#xff0c;是ushort[] → Hex字符串→byte[] → 翻转byte[] →BitConverter.ToInt32()&#xff0c;饶了一大圈&#xff1b;实际上可以直接转&#xff1b;这里也有小细节&#xff1a;使用BitCo…