将Python转换为Java:不断使索引越界

vbopmzt1  于 2023-10-14  发布在  Java
关注(0)|答案(2)|浏览(116)

我一直在尝试将python代码转换为Java,我有一个头部撞击时间试图找出为什么我的解决方案一直给我一个索引越界错误。有什么想法吗?我认为这是一个简单的语法或计数错误,但作为一个Python程序员,我看不出它在Java中不起作用。
Python代码:

def evaluate_formula(formula, variables, values):
    stack = []
    for char in formula:
        if char == '(':
            stack.append(char)
        elif char == ')':
            while stack[-1] != '(':
                operator = stack.pop()
                operand2 = stack.pop()
                operand1 = stack.pop()
                if operator == '&':
                    stack.append(operand1 and operand2)
                elif operator == '|':
                    stack.append(operand1 or operand2)
        elif char in variables:
            if char in values:
                stack.append(values[char])
            else:
                return None
        elif char == '~':
            if stack and stack[-1] == '~':
                stack.pop()
                if stack and stack[-1] == '(':
                    return None
            else:
                stack.append('~')
        elif char in ['&', '|']:
            stack.append(char)

    if len(stack) == 1 and type(stack[0]) == bool:
        return stack[0]
    else:
        return None

Java代码

public static String evaluateFormula(String str, char[] variableValues) {
        String evaluated = "";
        for (char c : str.toCharArray()) {
            if (Character.isAlphabetic(c)) {
                evaluated += variableValues[c - 'a'];
            } else if (c == '&') {
                int index = evaluated.length() - 1;
                char op1 = evaluated.charAt(index - 1);
                char op2 = evaluated.charAt(index);
                evaluated = evaluated.substring(0, index - 1) + (op1 == 'T' && op2 == 'T' ? 'T' : 'F');
            } else if (c == '|') {
                int index = evaluated.length() - 1;
                char op1 = evaluated.charAt(index - 1);
                char op2 = evaluated.charAt(index);
                evaluated = evaluated.substring(0, index - 1) + (op1 == 'T' || op2 == 'T' ? 'T' : 'F');
            } else if (c == '~') {
                int index = evaluated.length() - 1;
                char op = evaluated.charAt(index);
                
                evaluated = evaluated.substring(0, index - 1) + (op == 'T' ? 'F' : 'T');
            }
        }
        return evaluated;
    }
w8f9ii69

w8f9ii691#

如果公式格式不正确或缺少括号,则可能发生“索引越界”错误。要修复错误并确保代码正确处理边界,可以按如下方式修改代码:
python代码修复了边界问题:

def evaluate_formula(formula, variables, values):
    stack = []
    for char in formula:
        if char == '(':
            stack.append(char)
        elif char == ')':
            # Check for empty stack or missing opening parenthesis
            if not stack or stack[-1] != '(':
                return None

            while stack[-1] != '(':
                operator = stack.pop()
                operand2 = stack.pop()
                operand1 = stack.pop()
                if operator == '&':
                    stack.append(operand1 and operand2)
                elif operator == '|':
                    stack.append(operand1 or operand2)

            # Pop the opening parenthesis
            stack.pop()
        elif char in variables:
            if char in values:
                stack.append(values[char])
            else:
                return None
        elif char == '~':
            if stack and stack[-1] == '~':
                stack.pop()
                if stack and stack[-1] == '(':
                    return None
            else:
                stack.append('~')
        elif char in ['&', '|']:
            stack.append(char)

    # Ensure that there is only one element in the stack and it's a boolean
    if len(stack) == 1 and type(stack[0]) == bool:
        return stack[0]
    else:
        return None

java代码:
保存为:FormulaEvaluator.java

import java.util.Stack;

public class FormulaEvaluator {
    public static Boolean evaluateFormula(String formula, String[] variables, Boolean[] values) {
        Stack<Object> stack = new Stack<>();
        for (char c : formula.toCharArray()) {
            if (c == '(') {
                stack.push(c);
            } else if (c == ')') {
                if (stack.isEmpty() || !stack.peek().equals('(')) {
                    return null;
                }
                stack.pop(); // Remove the opening parenthesis

                while (!stack.isEmpty() && stack.peek() instanceof Boolean) {
                    Boolean operand2 = (Boolean) stack.pop();
                    char operator = (char) stack.pop();
                    Boolean operand1 = (Boolean) stack.pop();

                    if (operator == '&') {
                        stack.push(operand1 && operand2);
                    } else if (operator == '|') {
                        stack.push(operand1 || operand2);
                    }
                }
            } else if (contains(variables, c)) {
                int index = getIndex(variables, c);
                if (index != -1) {
                    stack.push(values[index]);
                } else {
                    return null;
                }
            } else if (c == '~') {
                if (!stack.isEmpty() && stack.peek().equals('~')) {
                    stack.pop();
                    if (!stack.isEmpty() && stack.peek().equals('(')) {
                        return null;
                    }
                } else {
                    stack.push('~');
                }
            } else if (c == '&' || c == '|') {
                stack.push(c);
            }
        }

        if (stack.size() == 1 && stack.peek() instanceof Boolean) {
            return (Boolean) stack.peek();
        } else {
            return null;
        }
    }

    private static boolean contains(String[] array, char c) {
        for (String s : array) {
            if (s.equals(String.valueOf(c))) {
                return true;
            }
        }
        return false;
    }

    private static int getIndex(String[] array, char c) {
        for (int i = 0; i < array.length; i++) {
            if (array[i].equals(String.valueOf(c))) {
                return i;
            }
        }
        return -1;
    }
}
qvsjd97n

qvsjd97n2#

使用 char01 来表示 bool 值。

Character evaluateFormula(String formula, String variables, String values) {
    Deque<Character> stack = new ArrayDeque<>();
    for (char c : formula.toCharArray())
        if (c == '(')
            stack.add(c);
        else if (c == ')')
            while (stack.getLast() != '(') {
                char operator = stack.pop();
                boolean operand2 = stack.pop() == 1;
                boolean operand1 = stack.pop() == 1;
                if (operator == '&') 
                    stack.add((char) (operand1 && operand2 ? 1 : 0));
                else if (operator == '|') 
                    stack.add((char) (operand1 || operand2 ? 1 : 0));
            }
        else if (variables.contains(String.valueOf(c)))
            if (values.contains(String.valueOf(c)))
                stack.add(values.charAt(c))
            else
                return null;
        else if (c == '~')
            if (!stack.isEmpty() && stack.getLast() == '~') {
                stack.pop();
                if (!stack.isEmpty() && stack.getLast() == '(')
                    return null;
            } else
                stack.add('~');
        else if (c == '&' || c == '|')
            stack.add(c);

    if (stack.size() == 1 && stack.getFirst() <= 1)
        return stack.getFirst();
    else
        return null;
}

这里是一个优化的版本,用于重用变量。

import static java.lang.String.valueOf;
Character evaluateFormula(String formula, String variables, String values) {
    Deque<Character> s = new ArrayDeque<>();
    char op;
    boolean op1, op2;
    for (char c : formula.toCharArray())
        switch (c) {
            case '(', '&', '|' -> s.add(c);
            case ')' -> {
                while (s.getLast() != '(') {
                    op = s.pop();
                    op1 = s.pop() == 1;
                    op2 = s.pop() == 1;
                    if (op == '&') s.add((char) (op1 && op2 ? 1 : 0));
                    else if (op == '|') s.add((char) (op1 || op2 ? 1 : 0));
                }
            }
            case '~' -> {
                if (!s.isEmpty() && s.getLast() == '~') {
                    s.pop();
                    if (!s.isEmpty() && s.getLast() == '(') return null;
                } else s.add('~');
            }
            default -> {
                if (variables.contains(valueOf(c)))
                    if (values.contains(valueOf(c))) s.add(values.charAt(c));
                    else return null;
            }
        }
    if (s.size() == 1 && s.getFirst() <= 1) return s.getFirst();
    else return null;
}

相关问题