华为OD机试-提取字符串中的最长数学表达式(Java 2024 D卷 100分)

题目描述

我们需要从给定的字符串中提取最长的合法简单数学表达式,并计算该表达式的值。如果字符串中没有合法的数学表达式,则返回0。合法的简单数学表达式只能包含数字(0-9)和符号(+、-、*)。表达式必须是最长的且合法的,操作符不能连续出现。

输入描述

  • 输入为一个字符串。

输出描述

  • 输出为表达式的值。

解题思路

  1. 遍历字符串:我们需要遍历字符串,寻找所有可能的合法表达式。
  2. 合法性检查:在遍历过程中,检查当前字符是否可以构成合法表达式的一部分。操作符不能连续出现。
  3. 记录最长表达式:记录下最长的合法表达式,并计算其值。
  4. 返回结果:返回最长表达式的值,如果没有合法表达式,则返回0。

代码实现

Java
import java.util.Stack;

public class Solution {
    public long longestExpression(String s) {
        long maxVal = 0;
        String maxExp = "";
        for (int i = 0; i < s.length(); i++) {
            for (int j = i + 1; j <= s.length(); j++) {
                String substr = s.substring(i, j);
                if (isValidExpression(substr)) {
                    if (substr.length() > maxExp.length()) {
                        maxExp = substr;
                        maxVal = evaluateExpression(substr);
                    }
                }
            }
        }
        return maxVal;
    }

    private boolean isValidExpression(String s) {
        if (s.isEmpty()) return false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (!Character.isDigit(c) && c != '+' && c != '-' && c != '*') {
                return false;
            }
            if (i > 0 && !Character.isDigit(s.charAt(i - 1)) {
                if (!Character.isDigit(c)) {
                    return false;
                }
            }
        }
        return true;
    }

    private long evaluateExpression(String s) {
        Stack<Long> numbers = new Stack<>();
        Stack<Character> operators = new Stack<>();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (Character.isDigit(c)) {
                long num = 0;
                while (i < s.length() && Character.isDigit(s.charAt(i))) {
                    num = num * 10 + (s.charAt(i) - '0');
                    i++;
                }
                i--;
                numbers.push(num);
            } else if (c == '+' || c == '-' || c == '*') {
                while (!operators.isEmpty() && precedence(operators.peek()) >= precedence(c)) {
                    numbers.push(applyOp(operators.pop(), numbers.pop(), numbers.pop()));
                }
                operators.push(c);
            }
        }
        while (!operators.isEmpty()) {
            numbers.push(applyOp(operators.pop(), numbers.pop(), numbers.pop()));
        }
        return numbers.pop();
    }

    private int precedence(char op) {
        if (op == '+' || op == '-') return 1;
        if (op == '*') return 2;
        return 0;
    }

    private long applyOp(char op, long b, long a) {
        switch (op) {
            case '+': return a + b;
            case '-': return a - b;
            case '*': return a * b;
        }
        return 0;
    }
}
Python
def longest_expression(s):
    def is_valid_expression(expr):
        if not expr:
            return False
        for i, char in enumerate(expr):
            if not char.isdigit() and char not in {'+', '-', '*'}:
                return False
            if i > 0 and not expr[i-1].isdigit():
                if not char.isdigit():
                    return False
        return True

    def evaluate_expression(expr):
        stack = []
        num = 0
        sign = '+'
        for i in range(len(expr)):
            if expr[i].isdigit():
                num = num * 10 + int(expr[i])
            if not expr[i].isdigit() or i == len(expr) - 1:
                if sign == '+':
                    stack.append(num)
                elif sign == '-':
                    stack.append(-num)
                elif sign == '*':
                    stack.append(stack.pop() * num)
                sign = expr[i]
                num = 0
        return sum(stack)

    max_val = 0
    max_exp = ""
    for i in range(len(s)):
        for j in range(i + 1, len(s) + 1):
            substr = s[i:j]
            if is_valid_expression(substr):
                if len(substr) > len(max_exp):
                    max_exp = substr
                    max_val = evaluate_expression(substr)
    return max_val
C++
#include <string>
#include <stack>
#include <algorithm>

using namespace std;

class Solution {
public:
    long longestExpression(string s) {
        long maxVal = 0;
        string maxExp = "";
        for (size_t i = 0; i < s.length(); ++i) {
            for (size_t j = i + 1; j <= s.length(); ++j) {
                string substr = s.substr(i, j - i);
                if (isValidExpression(substr)) {
                    if (substr.length() > maxExp.length()) {
                        maxExp = substr;
                        maxVal = evaluateExpression(substr);
                    }
                }
            }
        }
        return maxVal;
    }

private:
    bool isValidExpression(const string& s) {
        if (s.empty()) return false;
        for (size_t i = 0; i < s.length(); ++i) {
            char c = s[i];
            if (!isdigit(c) && c != '+' && c != '-' && c != '*') {
                return false;
            }
            if (i > 0 && !isdigit(s[i - 1])) {
                if (!isdigit(c)) {
                    return false;
                }
            }
        }
        return true;
    }

    long evaluateExpression(const string& s) {
        stack<long> numbers;
        stack<char> operators;
        for (size_t i = 0; i < s.length(); ++i) {
            char c = s[i];
            if (isdigit(c)) {
                long num = 0;
                while (i < s.length() && isdigit(s[i])) {
                    num = num * 10 + (s[i] - '0');
                    ++i;
                }
                --i;
                numbers.push(num);
            } else if (c == '+' || c == '-' || c == '*') {
                while (!operators.empty() && precedence(operators.top()) >= precedence(c)) {
                    numbers.push(applyOp(operators.top(), numbers.top()));
                    operators.pop();
                    numbers.pop();
                }
                operators.push(c);
            }
        }
        while (!operators.empty()) {
            numbers.push(applyOp(operators.top(), numbers.top()));
            operators.pop();
            numbers.pop();
        }
        return numbers.top();
    }

    int precedence(char op) {
        if (op == '+' || op == '-') return 1;
        if (op == '*') return 2;
        return 0;
    }

    long applyOp(char op, long b, long a) {
        switch (op) {
            case '+': return a + b;
            case '-': return a - b;
            case '*': return a * b;
        }
        return 0;
    }
};
JavaScript
function longestExpression(s) {
    function isValidExpression(expr) {
        if (!expr) return false;
        for (let i = 0; i < expr.length; i++) {
            const char = expr[i];
            if (!/\d/.test(char) && !['+', '-', '*'].includes(char)) {
                return false;
            }
            if (i > 0 && !/\d/.test(expr[i - 1])) {
                if (!/\d/.test(char)) {
                    return false;
                }
            }
        }
        return true;
    }

    function evaluateExpression(expr) {
        const stack = [];
        let num = 0;
        let sign = '+';
        for (let i = 0; i < expr.length; i++) {
            if (/\d/.test(expr[i])) {
                num = num * 10 + parseInt(expr[i]);
            }
            if (!/\d/.test(expr[i]) || i === expr.length - 1) {
                if (sign === '+') {
                    stack.push(num);
                } else if (sign === '-') {
                    stack.push(-num);
                } else if (sign === '*') {
                    stack.push(stack.pop() * num);
                }
                sign = expr[i];
                num = 0;
            }
        }
        return stack.reduce((a, b) => a + b, 0);
    }

    let maxVal = 0;
    let maxExp = "";
    for (let i = 0; i < s.length; i++) {
        for (let j = i + 1; j <= s.length; j++) {
            const substr = s.substring(i, j);
            if (isValidExpression(substr)) {
                if (substr.length > maxExp.length) {
                    maxExp = substr;
                    maxVal = evaluateExpression(substr);
                }
            }
        }
    }
    return maxVal;
}

总结

这道题目要求我们从字符串中提取最长的合法数学表达式,并计算其值。我们通过遍历字符串、检查表达式的合法性、记录最长表达式并计算其值来解决这个问题。代码实现了Java、Python、C++和JavaScript四种语言的解决方案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝白咖啡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值