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

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

  • romanToInt Function:

    • Used const for result (which gets modified later) — should use let instead.
    • Un-declared i variable in loops (creates global scope leaks and unexpected behavior).
    • Roman-to-Arabic conversion didn’t handle end-of-string edge cases (risk of undefined when accessing next character).
    • Arabic-to-Roman conversion used an unordered object, so it couldn’t generate valid subtractive numerals like IV (instead of IIII).
    • Vague parameter c — renamed to mode for clarity (1 = Roman → Arabic, 2 = Arabic → Roman).
  • calculator Function:

    • 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 Error instead of descriptive error objects).
    • Minor stack order and input validation logic gaps.

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:

  1. calculate('1 + 2') → "3" ✅
  2. calculate('VI / III') → "II" (Note: VI = 6, III = 3; 6/3 = 2 which is II — your example listed III which is likely a typo) ✅
  3. calculate('I - II') → "" (1-2 = -1, returns empty string) ✅
  4. calculate('I + 1') → Throws Error: Invalid input: Cannot mix Roman and Arabic numerals ✅
  5. calculate('I') → Throws Error: Invalid input: No operator provided ✅
  6. calculate('1 + 1 + 1') → Throws Error: Invalid input: Multiple operators are not allowed ✅

内容的提问来源于stack exchange,提问作者Aisin Dimon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 10:16:35