1、题目描述
罗马数字包含以下七种字符: I (1)、V (5)、X (10)、L (50)、C (100)、D (500)、M (1000)。罗马数字通常从左到右按值递减的顺序书写,但也存在特殊情况:小值在大值左侧时,表示大值减去小值(如 IV=4、IX=9、XL=40 等)。给定一个罗马数字字符串,将其转换为对应的整数。
2、解题思路
2.1核心原则 罗马数字的转换核心在于处理两种字符排列情况: 正常情况:字符对应值从左到右递减,直接累加每个字符的值; 特殊情况:当前字符对应值小于下一个字符对应值,用总和减去当前值(后续会累加下一个大值,等价于 “大值 – 小值”)。 * 2.2实现方案 枚举定义:用枚举 RomanNumber 存储所有罗马字符的枚举项,建立字符与枚举的映射关系; 值映射函数:通过 enumToValue 函数将枚举项转换为对应的整数(如 I→1、V→5); 字符转枚举函数:通过 charToEnum 函数将输入字符串中的字符转换为对应的枚举项; 遍历计算:遍历罗马数字字符串,对每个字符: 获取当前字符对应的整数值 currentnumber; 若存在下一个字符,获取下一个字符对应的整数值 next; 比较 currentnumber 和 next:若当前值更小则减,否则加,累计得到结果。 2.3代码实现
#include<string.h>
// 定义罗马数字对应的枚举类型
enum RomanNumber{
I,
V,
X,
L,
C,
D,
M
};
// 枚举项转换为对应整数
int enumToValue(enum RomanNumber n)
{
switch(n){
case I:
return 1;
case V:
return 5;
case X:
return 10;
case L:
return 50;
case C:
return 100;
case D:
return 500;
case M:
return 1000;
default:
return 0;
}
}
// 字符转换为对应枚举项
enum RomanNumber charToEnum(char n)
{
switch(n){
case 'I':
return I;
case 'V':
return V;
case 'X':
return X;
case 'L':
return L;
case 'C':
return C;
case 'D':
return D;
case 'M':
return M;
default:
return I; // 非法字符默认返回I,不影响核心逻辑
}
}
// 罗马数字字符串转整数核心函数
int romanToInt(char* s) {
int len = strlen(s); // 获取字符串长度
int sum = 0; // 存储转换结果
// 遍历字符串每个字符
for(int i = 0; i < len; i++)
{
// 得到当前字符的枚举项及对应整数
enum RomanNumber current = charToEnum(s[i]);
int currentnumber = enumToValue(current);
// 初始化下一个字符的值为0
int next = 0;
// 若不是最后一个字符,获取下一个字符的对应整数
if(i < len – 1)
{
enum RomanNumber nextnumber = charToEnum(s[i+1]);
next = enumToValue(nextnumber);
}
// 核心判断:当前值小于下一个值则减,否则加
if(currentnumber < next)
{
sum -= currentnumber;
}
else{
sum += currentnumber;
}
}
return sum;
}
3、代码解析
3.1枚举与映射函数 枚举与映射函数 枚举 RomanNumber:按罗马字符常用顺序定义枚举项,为每个罗马字符分配唯一枚举标识,便于后续映射; enumToValue 函数:通过 switch 语句将枚举项转换为实际整数,是枚举与数值的桥梁; charToEnum 函数:将输入字符串中的字符转换为对应枚举项,解决 “字符→数值” 的间接映射问题。 3.2核心逻辑 循环次数等于字符串长度len,保证字符串的所有字符全都被处理 通过if(x<len-1)来判断是否为最后一个字符,避免数组越界 核心判断 if(currentnumber < next): 示例 1(正常情况):输入 “VI”,V(5) > I(1) → 累加 5+1=6; 示例 2(特殊情况):输入 “IV”,I(1) < V(5) → 先减 1,再累加 5,结果 4; 示例 3(复杂情况):输入 “MCMXCIV”,遍历过程: M (1000) > C (100) → 加 1000(sum=1000); C (100) < M (1000) → 减 100(sum=900); M (1000) > X (10) → 加 1000(sum=1900); X (10) < C (100) → 减 10(sum=1890); C (100) > I (1) → 加 100(sum=1990); I (1) < V (5) → 减 1(sum=1989); V (5) 是最后一个字符 → 加 5(sum=1994),最终返回 1994。
4、复杂度分析
n为罗马数组字符串的长发,循环一次,每次循环的switch语句和就加减运算都是常规操作,总时间与字符串长度线性相关 空间复杂度分析:仅使用固定数量的变量,未开辟数组链表等等动态空间,所以为常数级
5、优势与注意事项
5.1优势 采用枚举类型使代码逻辑更清晰,罗马字符与枚举项的映射直观,便于维护; 避免使用额外数据结构(如数组映射),空间开销最小; 一次遍历完成转换,时间效率最优。 5.2注意事项 枚举项本身不存储数值,需通过 enumToValue 函数转换,不可直接使用枚举项进行数值比较; 需处理字符串边界(最后一个字符无下一个字符,next 默认为 0,避免越界访问); 非法字符默认返回 I,若需严格校验输入,可在 charToEnum 函数的 default 分支返回特殊值并在主函数中处理。


