JavaScript罗马数字与阿拉伯数字计算器代码调试求助
Fixing Your Roman Numeral & Arabic Number Calculator
Let’s fix your calculator step by step. I’ve gone through your code and spotted several key issues that were causing it to fail your required rules. Here’s the breakdown and corrected solution:
Key Issues in the Original Code
romanToIntFunction:- Used
constforresult(which gets modified later) — should useletinstead. - Un-declared
ivariable in loops (creates global scope leaks and unexpected behavior). - Roman-to-Arabic conversion didn’t handle end-of-string edge cases (risk of
undefinedwhen accessing next character). - Arabic-to-Roman conversion used an unordered object, so it couldn’t generate valid subtractive numerals like
IV(instead ofIIII). - Vague parameter
c— renamed tomodefor clarity (1 = Roman → Arabic, 2 = Arabic → Roman).
- Used
calculatorFunction:- Returned empty string for single-value inputs (like
"I"or"1") instead of throwing an error (violates rule 5). - Roman numeral parsing loop had no
i++, causing infinite loops. - Incorrectly rejected single-digit Arabic numbers (your code threw errors for 1-9, which is invalid).
- Threw errors for negative Roman results instead of returning empty string (violates rule 3).
- Vague error throwing (just
throw Errorinstead of descriptive error objects). - Minor stack order and input validation logic gaps.
- Returned empty string for single-value inputs (like
Corrected Code
function romanToInt(input, mode) { // Include subtractive combinations for valid Roman numeral generation const sym = { 'M': 1000, 'CM': 900, 'D': 500, 'CD': 400, 'C': 100, 'XC': 90, 'L': 50, 'XL': 40, 'X': 10, 'IX': 9, 'V': 5, 'IV': 4, 'I': 1 }; // Mode 1: Convert Roman numeral to integer if (mode === 1) { let result = 0; for (let i = 0; i < input.length; i++) { const curVal = sym[input[i]]; const nextVal = sym[input[i + 1]]; // Handle subtractive pairs (e.g., IV, IX) if (nextVal && curVal < nextVal) { result += nextVal - curVal; i++; // Skip next character since we processed it } else { result += curVal; } } return result; } // Mode 2: Convert integer to Roman numeral else if (mode === 2) { let result = ""; let num = input; // Iterate from largest to smallest value to build valid numerals for (const [romanChar, value] of Object.entries(sym)) { while (num >= value) { result += romanChar; num -= value; } } return result; } } function calculate(s) { const trimmedInput = s.trim(); // Rule 5: Single value (no operator) throws error if (!trimmedInput.match(/[+\-*/]/)) { throw new Error("Invalid input: No operator provided"); } let isArabic = false; let isRoman = false; let operator = null; const values = []; const romanChars = "IVXLCDM"; let i = 0; while (i < trimmedInput.length) { const char = trimmedInput[i]; // Skip spaces if (char === ' ') { i++; continue; } // Handle operators if (['+', '-', '*', '/'].includes(char)) { if (operator !== null) { // Rule 6: Multiple operators throw error throw new Error("Invalid input: Multiple operators are not allowed"); } operator = char; i++; continue; } // Handle Arabic numbers if (/[0-9]/.test(char)) { if (isRoman) { // Rule 4: Mixed number types throw error throw new Error("Invalid input: Cannot mix Roman and Arabic numerals"); } isArabic = true; let numStr = ""; while (i < trimmedInput.length && /[0-9]/.test(trimmedInput[i])) { numStr += trimmedInput[i]; i++; } values.push(parseInt(numStr, 10)); continue; } // Handle Roman numerals if (romanChars.includes(char)) { if (isArabic) { // Rule 4: Mixed number types throw error throw new Error("Invalid input: Cannot mix Roman and Arabic numerals"); } isRoman = true; let romanStr = ""; while (i < trimmedInput.length && romanChars.includes(trimmedInput[i])) { romanStr += trimmedInput[i]; i++; } values.push(romanToInt(romanStr, 1)); continue; } // Invalid character detected throw new Error("Invalid input: Unsupported character"); } // Ensure exactly two operands and one operator if (values.length !== 2 || !operator) { throw new Error("Invalid input: Must have exactly two operands and one operator"); } const [num1, num2] = values; let result; // Perform calculation based on operator switch (operator) { case '+': result = num1 + num2; break; case '-': result = num1 - num2; break; case '*': result = num1 * num2; break; case '/': // Integer division (truncate towards zero) result = Math.trunc(num1 / num2); break; default: throw new Error("Invalid operator"); } // Handle Roman-specific rules if (isRoman) { // Rule 3: Negative or zero result returns empty string if (result <= 0) { return ""; } return romanToInt(result, 2); } // Return Arabic result as string return result.toString(); } module.exports = calculate;
Verification Against Your Rules
Let’s confirm each required case works as expected:
calculate('1 + 2')→"3"✅calculate('VI / III')→"II"(Note: VI = 6, III = 3; 6/3 = 2 which isII— your example listedIIIwhich is likely a typo) ✅calculate('I - II')→""(1-2 = -1, returns empty string) ✅calculate('I + 1')→ ThrowsError: Invalid input: Cannot mix Roman and Arabic numerals✅calculate('I')→ ThrowsError: Invalid input: No operator provided✅calculate('1 + 1 + 1')→ ThrowsError: Invalid input: Multiple operators are not allowed✅
内容的提问来源于stack exchange,提问作者Aisin Dimon
相关产品推荐
相关产品推荐

