Java每日精进·45天挑战·Day14

第一部分:逆波兰表达式求值

在编程中,逆波兰表达式(Reverse Polish Notation, RPN)是一种后缀表达式,它的特点是将运算符写在操作数的后面。这种表达式形式在处理算术运算时具有许多优点,尤其是它非常适合使用栈数据结构来进行求值。今天,我们将通过Java代码来实现一个逆波兰表达式的求值器。

逆波兰表达式的优点
  1. 无括号表达式无歧义:在逆波兰表达式中,由于运算符始终写在操作数的后面,因此即使去掉括号,表达式依然没有歧义。这使得解析表达式变得更加简单。

  2. 适合用栈操作:逆波兰表达式的求值过程非常适合用栈来实现。我们可以从左到右遍历表达式,遇到操作数时将其压入栈中,遇到运算符时从栈中弹出两个操作数进行计算,并将结果压回栈中。最终,栈顶元素即为表达式的结果。

Java实现

下面是一个Java类,它包含一个方法evalRPN,用于计算逆波兰表达式的值。

import java.util.Stack;

public class Solution {
    public int evalRPN(String[] tokens) {
        Stack stack = new Stack<>();

        for (String token : tokens) {
            // Check if the token is an operator
            if (token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/")) {
                int operand2 = stack.pop();
                int operand1 = stack.pop();
                int result = 0;
                switch (token) {
                    case "+":
                        result = operand1 + operand2;
                        break;
                    case "-":
                        result = operand1 - operand2;
                        break;
                    case "*":
                        result = operand1 * operand2;
                        break;
                    case "/":
                        // Perform integer division towards zero
                        result = operand1 / operand2;
                        break;
                }
                stack.push(result);
            } else {
                // The token is an operand, convert it to integer and push it to the stack
                stack.push(Integer.parseInt(token));
            }
        }

        // The final result will be at the top of the stack
        return stack.pop();
    }

    public static void main(String[] args) {
        Solution solution = new Solution();

        String[] tokens1 = {"2","1","+","3","*"};
        System.out.println(solution.evalRPN(tokens1)); // Output: 9

        String[] tokens2 = {"4","13","5","/","+"};
        System.out.println(solution.evalRPN(tokens2)); // Output: 6

        String[] tokens3 = {"10","6","9","3","+","-11","*","/","*","17","+","5","+"};
        System.out.println(solution.evalRPN(tokens3)); // Output: 22
    }
}

代码说明
  1. 栈的初始化:在evalRPN方法中,我们首先创建一个栈来存储操作数。

  2. 遍历表达式:我们使用一个for循环来遍历表达式中的每个token。

  3. 判断运算符:对于每个token,我们首先判断它是否为运算符。如果是运算符,则执行以下步骤:

    • 弹出两个操作数。
    • 根据运算符进行计算。
    • 将结果压入栈中。
  4. 处理操作数:如果token不是运算符,则将其转换为整数并压入栈中。

  5. 返回结果:最后,我们返回栈顶元素作为表达式的结果。

  6. 辅助方法:为了方便代码的阅读和维护,我们定义了两个辅助方法:isOperator用于判断一个字符串是否为运算符,evaluate用于根据运算符计算两个操作数的结果。

  7. 测试:在main方法中,我们创建了几个测试用例来验证实现的正确性。

通过上述内容,我们了解了逆波兰表达式的优点以及如何使用Java代码来实现一个逆波兰表达式的求值器。希望这对你有所帮助!

第二部分:高效判断字符串中字符是否全不同的算法实现

引言

在处理字符串数据时,我们经常需要判断一个字符串中的所有字符是否各不相同。这个问题在编程竞赛、面试以及日常开发中都非常常见。本文将介绍一种高效的算法,利用位运算来判断字符串中的字符是否全不同,并且不需要使用额外的数据结构。

问题描述

给定一个字符串s,我们需要判断该字符串中的所有字符是否各不相同。字符集限定为小写字母('a'到'z'),并且字符串的长度不超过100。

示例
  • 输入: s = "leetcode"

  • 输出: false

  • 输入: s = "abc"

  • 输出: true

算法思路

由于字符集只有26个小写字母,我们可以利用一个32位的整数(int类型)来表示这些字符的出现情况。每一位对应一个字母,如果该位为1,则表示对应的字母出现过,为0则表示未出现过。

具体步骤如下:

  1. 初始化:创建一个32位的整数checker,并将其初始化为0。

  2. 遍历字符串:对于字符串中的每个字符c,计算其对应的位掩码。由于c是小写字母,其ASCII值在97('a')到122('z')之间,所以我们可以通过(c - 'a')得到一个0到25之间的整数,然后左移1位(1 << (c - 'a'))得到一个位掩码。

  3. 检查并设置:使用位与运算checker & mask检查checker的对应位是否为1。如果是,说明字符c已经出现过,返回false。如果字符c未出现过,则使用位或运算checker |= maskchecker的对应位设置为1。

  4. 返回结果:如果遍历完整个字符串都没有发现重复的字符,则返回true

代码实现

下面是Java语言的实现代码:

public class UniqueCharacters {
    public boolean isUnique(String s) {
        if (s == null || s.length() > 26) {
            return false; // 如果字符串为空或长度超过26,则不可能所有字符都不同
        }

        int checker = 0;
        for (char c : s.toCharArray()) {
            int mask = 1 << (c - 'a');
            if ((checker & mask) != 0) {
                return false;
            }
            checker |= mask;
        }
        return true;
    }

    public static void main(String[] args) {
        UniqueCharacters uc = new UniqueCharacters();
        System.out.println(uc.isUnique("leetcode")); // 输出: false
        System.out.println(uc.isUnique("abc")); // 输出: true
    }
}

算法分析
  • 时间复杂度:O(n),其中n是字符串的长度,因为我们只需要遍历一次字符串。
  • 空间复杂度:O(1),因为我们只使用了一个固定大小的整数来存储字符出现的信息。
总结

本文介绍了一种高效的算法,利用位运算来判断字符串中的字符是否全不同。这种方法不仅简单易懂,而且具有较低的时间复杂度和空间复杂度。在处理类似问题时,我们可以优先考虑这种方法。希望本文对你有所帮助!

你可能感兴趣的:(开发语言,算法)