C#罗马数字转整数触发数组索引越界错误排查求助
问题分析与修复
错误原因
触发数组索引越界的核心问题在第二个for循环中:
for (int i = 0; i < inputValues.Length; i++) { if (inputValues[i] >= inputValues[i+1]) // 当i是最后一个索引时,i+1超出数组范围 { inputValuesAfter[i] = inputValues[i]; } else if (inputValues[i] < inputValues[i+1]) { inputValuesAfter[i] = inputValues[i+1] - inputValues[i]; i++; } }
数组索引从0开始,当i遍历到数组最后一个元素(索引为inputValues.Length - 1)时,i+1会超出数组的最大索引范围,直接触发Index outside of bounds of the array错误。
你输入长罗马数字时看似正常是巧合:比如"MCMXIV"长度为6,循环到i=4时触发了i++,让i直接变成5,此时循环条件i < 6成立,但执行inputValues[i+1]时依然会越界,只是测试时未暴露,本质上逻辑存在严重边界问题。
修复方案
修改循环条件避免访问超出范围的索引,同时单独处理最后一个元素,还可以去掉冗余的inputValuesAfter数组直接计算结果:
using System; public class Program { public static void Main() { Console.Write("Input:"); string s = Console.ReadLine(); int print = RomanToInt(s); Console.WriteLine($"Result is: {print}"); static int RomanToInt(string s) { int[] decimalValues = new int[7] { 1, 5, 10, 50, 100, 500, 1000}; int[] inputValues = new int[s.Length]; for (int i = 0; i < s.Length; i++) { if (s[i] == 'I') inputValues[i] = decimalValues[0]; else if (s[i] == 'V') inputValues[i] = decimalValues[1]; else if (s[i] == 'X') inputValues[i] = decimalValues[2]; else if (s[i] == 'L') inputValues[i] = decimalValues[3]; else if (s[i] == 'C') inputValues[i] = decimalValues[4]; else if (s[i] == 'D') inputValues[i] = decimalValues[5]; else if (s[i] == 'M') inputValues[i] = decimalValues[6]; } int result = 0; // 循环仅遍历到倒数第二个元素,避免访问i+1越界 for (int i = 0; i < inputValues.Length - 1; i++) { if (inputValues[i] >= inputValues[i+1]) { result += inputValues[i]; } else { result += inputValues[i+1] - inputValues[i]; i++; // 跳过下一个元素,防止重复计算 } } // 单独处理最后一个元素 if (inputValues.Length > 0) { result += inputValues[inputValues.Length - 1]; } return result; } } }
额外优化建议
- 用
Dictionary<char, int>替换冗长的if-else判断,代码更简洁:var romanMap = new Dictionary<char, int> { {'I',1}, {'V',5}, {'X',10}, {'L',50}, {'C',100}, {'D',500}, {'M',1000} }; - 无需创建
inputValues数组,直接遍历原字符串时计算结果,节省内存开销。
内容的提问来源于stack exchange,提问作者Yusuf Dogan
相关产品推荐
相关产品推荐

