罗马数字相加C++程序挂起超时问题解决咨询
解决罗马数字相加程序超时挂起的问题
看起来你的程序出现超时挂起的核心原因是输入处理逻辑存在死循环风险,当输入流结束(比如测试用例输入完毕、用户按下终止输入的快捷键)时,cin.get()会读取到EOF,此时你的循环条件t != '\n'永远成立,导致程序无限循环,最终触发时间限制。
具体问题分析
看你处理第一个罗马数字的循环:
cin.get(t); while(t!='\n') { s=t; cin.get(t); // ... 处理逻辑 }
当输入流中没有更多字符时,cin.get(t)会将t设置为EOF(一个不等于'\n'的特殊值),此时循环条件t != '\n'始终为真,程序会一直卡在循环里,无法继续执行后续代码,自然就超时了。第二个罗马数字的处理循环也存在完全相同的问题。
修复步骤
- 在循环条件中加入EOF判断:每次读取后检查是否到达输入流末尾,避免死循环。
- 改用更可靠的整行读取方式:使用
getline(cin, string)来读取完整的罗马数字字符串,这样处理起来更直观,也能避免逐个字符读取的繁琐和潜在问题。 - 提取重复逻辑为函数:你现在处理两个罗马数字的代码几乎完全重复,把罗马数字转整数的逻辑写成一个函数,既减少冗余,也更容易维护。
优化后的完整代码
#include <iostream> #include <string> using namespace std; // 将罗马数字字符串转换为整数 int romanToInt(const string& roman) { int result = 0; int n = roman.size(); for (int i = 0; i < n; ++i) { // 当前字符的值 int current = 0; switch(roman[i]) { case 'I': current = 1; break; case 'V': current = 5; break; case 'X': current = 10; break; case 'L': current = 50; break; case 'C': current = 100; break; case 'D': current = 500; break; case 'M': current = 1000; break; default: return 0; // 非法字符,返回0 } // 如果当前字符小于下一个字符,减去当前值;否则加上 if (i < n - 1) { int next = 0; switch(roman[i+1]) { case 'I': next = 1; break; case 'V': next = 5; break; case 'X': next = 10; break; case 'L': next = 50; break; case 'C': next = 100; break; case 'D': next = 500; break; case 'M': next = 1000; break; } if (current < next) { result -= current; } else { result += current; } } else { // 最后一个字符,直接加 result += current; } } return result; } // 将整数转换为罗马数字字符串 string intToRoman(int num) { // 定义整数和对应罗马数字的映射,包含特殊组合(如4=IV, 9=IX等) const int values[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; const string symbols[] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}; string roman; for (int i = 0; i < 13; ++i) { while (num >= values[i]) { roman += symbols[i]; num -= values[i]; } } return roman; } int main() { string roman1, roman2; // 读取两个罗马数字字符串 getline(cin, roman1); getline(cin, roman2); int num1 = romanToInt(roman1); int num2 = romanToInt(roman2); int sum = num1 + num2; cout << intToRoman(sum) << endl; return 0; }
额外说明
- 新代码使用
getline读取整行,避免了逐个字符读取的死循环问题,同时处理输入更简洁。 - 把罗马数字和整数的互转逻辑封装成函数,代码结构更清晰,也方便后续调试和修改。
- 整数转罗马数字的部分使用了映射数组的方式,比你原来的多分支
if-else更简洁高效,也能覆盖所有可能的数值情况。
内容的提问来源于stack exchange,提问作者Indriti
相关产品推荐
相关产品推荐

