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

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

题目

罗马数字包含以下七种字符: 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.mrgr.cn/news/64874.html

相关文章:

  • 【项目方案】2024软件技术软件项目建设方案,项目建设总纲(word原件)
  • Socket篇(网络通信)
  • Redis常见面试题概览——针对实习面试
  • 市象独家|百度副总裁陈一凡轮岗MEG;美团开放两项员工专属优惠 美团
  • word试题转excel(最简单的办法,无格式要求)
  • 如何利用低代码开源框架实现高效开发?
  • Linux入门(2)
  • 手机App防沉迷系统
  • ValueError: images do not match
  • GB/T 28046.3-2011 道路车辆 电气及电子设备的环境条件和试验 第3部分:机械负荷(3)
  • 14. 数据的输入输出
  • 第六十三周周报 GGNN
  • scIDST:弱监督学习推断单细胞转录组数据中的疾病进展阶段
  • 数据结构与算法(1)
  • 从一到无穷大 #40:DB AI 融合
  • 第三次RHCSA作业
  • Java入门 (6) -- 动态编程的奥秘
  • 视频QoE测量学习笔记(二)
  • masm汇编字符输入输出演示
  • 20221403郑骁恒-TLCP 协议验证
  • IDEA控制台日志乱码问题
  • 我主编的电子技术实验手册(22)——RC并联电路
  • jsweb2
  • 从“被围剿”到“满堂彩”,3A游戏让中国游戏人挺直脊背
  • RAG流程
  • [vulnhub]DC:7