MST

星途 面试题库

面试题:JavaScript 算术表达式复杂边界场景综合处理

在JavaScript中,对于包含多种数据类型(如BigInt、Number、字符串等)混合运算的复杂算术表达式,描述如何确保在各种边界情况下(如极端数值、数据类型转换失败等)正确处理并返回合理结果。请提供实现思路及关键代码片段示例。
10.7万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 数据类型检查与转换:在进行运算前,先检查操作数的数据类型。对于BigIntNumber类型,要确保它们在运算时类型统一。BigIntNumber不能直接混合运算,需要根据具体需求进行转换。例如,如果需要精确处理大整数,将Number转换为BigInt;如果允许一定精度损失,将BigInt转换为Number。对于字符串类型,要判断其是否可转换为数字,如果可以则进行转换,否则抛出异常。
  2. 边界情况处理
    • 极端数值:对于Number类型,要处理Number.MAX_SAFE_INTEGERNumber.MIN_SAFE_INTEGER等边界值。对于BigInt,要处理极大或极小的整数值。
    • 数据类型转换失败:当字符串无法转换为数字时,应抛出明确的错误信息,而不是返回NaN导致后续运算结果不准确。
  3. 运算顺序:遵循数学中的运算优先级,使用括号明确运算顺序,避免因优先级问题导致错误结果。

关键代码片段示例

function safeEval(expression) {
    const tokens = expression.split(/(\d+|\+|\-|\*|\/|%)/).filter(Boolean);
    let result;
    let currentTokenIndex = 0;

    function nextToken() {
        return tokens[currentTokenIndex++];
    }

    function parseNumber() {
        const token = nextToken();
        if (/^\d+$/.test(token)) {
            if (token.length > 16) {
                return BigInt(token);
            }
            return Number(token);
        }
        throw new Error('Invalid number: ' + token);
    }

    function parseFactor() {
        let value = parseNumber();
        while (true) {
            const operator = tokens[currentTokenIndex];
            if (operator === '*' || operator === '/' || operator === '%') {
                nextToken();
                const right = parseNumber();
                if (typeof value === 'bigint' || typeof right === 'bigint') {
                    value = typeof value === 'bigint'? value : BigInt(value);
                    right = typeof right === 'bigint'? right : BigInt(right);
                    if (operator === '*') value = value * right;
                    else if (operator === '/') value = value / right;
                    else value = value % right;
                } else {
                    if (operator === '*') value = value * right;
                    else if (operator === '/') value = value / right;
                    else value = value % right;
                }
            } else {
                break;
            }
        }
        return value;
    }

    function parseExpression() {
        let value = parseFactor();
        while (true) {
            const operator = tokens[currentTokenIndex];
            if (operator === '+' || operator === '-') {
                nextToken();
                const right = parseFactor();
                if (typeof value === 'bigint' || typeof right === 'bigint') {
                    value = typeof value === 'bigint'? value : BigInt(value);
                    right = typeof right === 'bigint'? right : BigInt(right);
                    if (operator === '+') value = value + right;
                    else value = value - right;
                } else {
                    if (operator === '+') value = value + right;
                    else value = value - right;
                }
            } else {
                break;
            }
        }
        return value;
    }

    result = parseExpression();
    if (currentTokenIndex!== tokens.length) {
        throw new Error('Unexpected token at the end of expression');
    }
    return result;
}
// 使用示例
const complexExpression = '123 + 456 * 789 - 1234567890123456789n';
try {
    const result = safeEval(complexExpression);
    console.log(result);
} catch (error) {
    console.error(error.message);
}

上述代码通过自定义的safeEval函数来解析并计算包含多种数据类型的算术表达式。首先将表达式拆分为标记(token),然后按照运算优先级进行解析和计算,在运算过程中处理数据类型转换和边界情况。