You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

罗马数字转阿拉伯数字代码在LeetCode报Runtime Error,VS正常求助

问题根源与解决方案

你的代码在LeetCode上触发Runtime Error的核心原因,是误用sizeof(s)获取字符串长度——这是C语言新手极易踩的数组/指针区别坑。

为什么VS里正常,LeetCode里报错?

  • 在Visual Studio的代码中,s是数组类型(char s[] = {'M','C',...}),sizeof(s)会计算整个数组的总字节数,刚好等于罗马数字的字符数7,所以循环逻辑正常。
  • 但在LeetCode的函数参数中,char *s是指针类型,sizeof(s)得到的是当前系统下指针的固定大小(64位系统是8字节,32位是4字节),完全不是字符串的实际长度。

当测试用例"MCMXCIV"有7个字符时,你用指针大小(比如4)作为循环上限nchar,后续循环中会出现两种越界行为:

  1. 读取s[4]、s[5]等超出nchar范围的字符
  2. 往长度为4的vals数组中写入vals[4]、vals[5]等位置
    最终触发AddressSanitizer检测到的heap-buffer-overflow错误。

修正后的代码(保留vals数组版本)

#include <string.h> // 必须包含strlen的头文件

int romanToInt(char * s){
    int nchar = strlen(s); // 用strlen获取字符串实际长度
    int vals[nchar];
    int sum = 0;

    // 罗马字符转数值,用switch更简洁
    for (int i = 0; i < nchar; i++) {
        switch(s[i]) {
            case 'I': vals[i] = 1; break;
            case 'V': vals[i] = 5; break;
            case 'X': vals[i] = 10; break;
            case 'L': vals[i] = 50; break;
            case 'C': vals[i] = 100; break;
            case 'D': vals[i] = 500; break;
            case 'M': vals[i] = 1000; break;
            default: vals[i] = 0; // 处理非法输入,可选
        }
    }

    // 求和逻辑不变
    for (int i = 0; i < nchar; i++) {
        if (i != nchar - 1 && vals[i] < vals[i + 1]) {
            sum += vals[i + 1] - vals[i];
            i++;
        } else {
            sum += vals[i];
        }
    }
    return sum;
}

更高效的优化版本(去掉vals数组)

可以直接在循环中计算数值,省去额外数组的内存开销:

#include <string.h>

// 单独提取罗马字符转数值的函数,提升可读性
int getRomanVal(char c) {
    switch(c) {
        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;
    }
}

int romanToInt(char * s){
    int nchar = strlen(s);
    int sum = 0;
    int currentVal, nextVal;

    for (int i = 0; i < nchar; i++) {
        currentVal = getRomanVal(s[i]);
        // 仅当不是最后一个字符时,判断是否需要做减法
        if (i < nchar - 1) {
            nextVal = getRomanVal(s[i+1]);
            if (currentVal < nextVal) {
                sum += nextVal - currentVal;
                i++; // 跳过下一个字符,避免重复计算
                continue;
            }
        }
        sum += currentVal;
    }
    return sum;
}

内容的提问来源于stack exchange,提问作者Rafael Carro Gaudim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 19:30:56