【栈】227. 基本计算器 II & 224. 基本计算器

227. 基本计算器 II

题目

227. 基本计算器 II

实现一个基本的计算器来计算一个简单的字符串表达式的值。

字符串表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格 。 整数除法仅保留整数部分。

示例 1:

输入: “3+2*2”
输出: 7
示例 2:

输入: " 3/2 "
输出: 1
示例 3:

输入: " 3+5 / 2 "
输出: 5

解法

利用栈将四则运算化简成加法运算

此算法的思路很简单,先把乘除法的值计算出来,最终将所有的运算简化成只有加法。

  1. 先跳过空格
  2. 出现了数字则记录整个数字是多少,然后根据之前的运算符决定下一步:
  • 如果是加号’+’,说明前面的运算独立于以后的运算,可以将结果暂时放入栈;
  • 如果是减号’-’,可以看成-1 * tempNum,然后将-tempNum入栈;
  • 如果是乘号’*‘或者除号’/’,由于前面的运算独立于此,可以先计算lastNum和tempNum积,然后结果入栈。
  1. 最后将栈中的所有元素相加就是答案。
public int calculate(String s) {
        Deque<Integer> stack = new LinkedList<>();
        char[] arr = s.toCharArray();
        char lastOps = '+';
        for (int i = 0; i < s.length(); i++) {
            // 跳过空格
            if (arr[i] == ' ') {
                continue;
            }
            if (Character.isDigit(arr[i])) {
                int tempNum = arr[i] - '0';
                // 如果是数字则继续向后遍历计算出数字
                while (++i < s.length() && Character.isDigit(arr[i])) {
                    tempNum = tempNum * 10 + arr[i] - '0';
                }
                // 最后多了一个+1的操作,需要-1
                i--;
                // 判断运算符的类型:+则直接入栈、-将相反数入栈、*/则将栈顶元素出栈并运算
                if (lastOps == '+') {
                    stack.push(tempNum);
                } else if (lastOps == '-') {
                    stack.push(-tempNum);
                } else if (lastOps == '*') {
                    stack.push(stack.pop() * tempNum);
                } else {
                    stack.push(stack.pop() / tempNum);
                }
                // 如果是运算符则记录运算符
            } else {
                lastOps = arr[i];
            }
        }
        // 计算其中每个运算的值
        int num = 0;
        for (int i : stack) {
            num += i;
        }
        return num;

224. 基本计算器

题目

224. 基本计算器

实现一个基本的计算器来计算一个简单的字符串表达式 s 的值。

示例 1:

输入:s = “1 + 1”
输出:2

示例 2:

输入:s = " 2-1 + 2 "
输出:3

示例 3:

输入:s = “(1+(4+5+2)-3)+(6+8)”
输出:23

s 由数字、’+’、’-’、’(’、’)’、和 ’ ’ 组成

解法

本题与上面那题的区别在于本题包含括号。

方法一:逆向读取字符串并使用栈

因为表达式包含 嵌套括号,可以使用「栈」暂存带括号的中间变量和结果。

通过具体例子研究一般规律:

示例 3:

输入:s = “(1+(4+5+2)-3)+(6+8)”
输出:23

  • 逆序读取代字符串,遇到右括号 ) 表示须要暂存接下来的数字和符号遇到左括号 ( 表示可以结算在遇到 离当前最近 的右括号 ) 之间缓存的数值,由于是逆序读取,这个过程符合 后进先出 的规律,因此缓存的数据结构须要使用「栈」;
  • 如果参与计算的数由多个字符组成,例如:字符串 “123”,表示数值 123,逆序读取的时候可以这样转换:3 + 20 + 100,可以设置一个变量 n ,从 1 开始,接下来变为 10、100,这样 3 + 20 + 100 = 3 * 1 + 2 * 10 + 1 * 100;
  • 如果遇到的字符不是数字而是「运算符或者括号」,先把数字存入栈,然后
    • 如果是运算符,+ 存入 1,- 存入 -1;
    • 如果是括号,左括号结算(因为当前括号里的内容可以计算出来,计算完成以后成为另一个括号里的数参与计算),右括号缓存起来
  • 最后栈中还有元素,还应该做一次计算。

class Solution {

    private int RIGHT_BRACKET = ')';

    public int calculate(String s) {
        // 去除左右空格
        s = s.trim();
        // 如果以负号开始则在最前面补0
        if (s.charAt(0) == '-') {
            s = "0" + s;
        }
        int len = s.length();
        char[] chars = s.toCharArray();
        // 只使用一个栈(保存操作数和操作符)
        Deque<Integer> stack = new LinkedList<>();
        // 累计的位数,转换 123,从右向左,底数从 1 开始,依次为 10、100、……
        int n = 1;
        // 累积的操作数
        int operand = 0;
        // 从后往前遍历
        for (int i = len - 1; i >= 0; i--) {
            char c = chars[i];
            // 跳过空格
            if (c == ' ') {
                continue;
            }
            // 累积计算操作符
            if (Character.isDigit(c)) {
                operand = n * (c - '0') + operand;
                n *= 10;
                continue;
            }
            // 将之前的操作数保存到栈,并且初始化 operand 和 n
            if (n != 1) {
                stack.push(operand);
                n = 1;
                operand = 0;
            }
            // 加减操作都转化为加法
            if (c == '+') {
                stack.push(1);
                continue;
            }
            if (c == '-') {
                stack.push(-1);
                continue;
            }
            // 左括号结算(因为当前括号里的内容可以计算出来,计算完成以后成为另一个括号里的数参与计算)
            // 右括号缓存起来
            if (c == '(') {
                int res = evalExpr(stack);
                stack.pop();
                stack.push(res);
            } else {
                stack.push(RIGHT_BRACKET);
            }
        }
        // 最后的数字加入栈中
        if (n != 1) {
            stack.push(operand);
        }
        // 最后计算一下整体的结果
        return evalExpr(stack);
    }

    public int evalExpr(Deque<Integer> stack) {
        int res = 0;
        if (!stack.isEmpty()) {
            res = stack.pop();
        }
        // 每次取出一个操作符和运算的数进行计算
        while (stack.size() > 1 && stack.peek() != RIGHT_BRACKET) {
            res += stack.pop() * stack.pop();
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Xamarin.Forms 是一个跨平台开发框架,可用于开发运行在 iOS、Android 和 UWP 等多个平台的应用程序。所以在使用 Xamarin.Forms 开发计算器应用时,我们需要处理计算器的符号问题。 在计算器应用中,常用的计算符号有加法、减法、乘法和除法。我们可以使用 Xamarin.Forms 中的按钮控件来表示这些符号,并为这些按钮添加相应的点击事件处理逻辑。 首先,我们可以创建四个按钮来表示加法、减法、乘法和除法符号。例如,我们可以创建一个按钮来表示加法符号“+”,并在按钮的 Clicked 事件回调中执行加法运算的逻辑。 ```csharp var addButton = new Button { Text = "+" }; addButton.Clicked += (sender, e) => { // 执行加法运算的逻辑 // ... }; ``` 类似地,我们可以为减法、乘法和除法符号分别创建对应的按钮,并为它们的 Clicked 事件回调添加相应的逻辑。 在具体的运算逻辑中,我们可以使用 C# 中的数学运算符来执行相应的计算操作。例如,利用加法运算符进行加法运算,利用减法运算符进行减法运算,以此类推。 通过在 Xamarin.Forms 中创建按钮来表示计算器符号,并在相应的点击事件回调中执行相应的运算逻辑,我们可以实现一个简单的计算器应用,用于处理不同符号的计算操作。 ### 回答2: Xamarin.Forms是一个用于创建跨平台移动应用的工具集。对于计算器符号,我们可以结合Xamarin.Forms的特性和功能来实现。首先,我们可以使用XAML来创建界面布局,然后在代码中添加功能。 对于计算器符号,我们可以使用各种方式来实现。一种常见的方式是使用字体图标库,如FontAwesome或Material Design Icons。这些库提供了各种各样的符号图标,可以通过在XAML中引用设置图标。 另一种方式是使用图片作为符号。我们可以选择符号图片并将其包含在我们的项目中。然后,我们可以在XAML中使用Image控件来显示这些图片符号。 同时,我们还可以使用字符来表示符号。Xamarin.Forms允许在文本控件中使用Unicode字符。我们可以在XAML或代码中直接设置控件的文本属性并使用特定的Unicode字符表示计算器符号。 综上所述,对于Xamarin.Forms的计算器符号,我们可以通过使用字体图标库、图片或Unicode字符来实现。这取决于我们的需求和喜好。无论我们选择哪种方式,Xamarin.Forms都提供了丰富的功能和灵活的选项,使我们能够轻松实现并使用计算器符号。 ### 回答3: 在Xamarin.Forms中实现计算器符号的方法如下: 1. 创建一个Xamarin.Forms项目,选择适当的模板作为起点。 2. 在XAML中设计计算器的界面,包括数字按钮、操作符按钮和结果显示框。 3. 创建一个ViewModel类来处理计算逻辑。可以使用Command模式来处理按钮的点击事件和计算逻辑。 4. 在ViewModel中,使用逻辑运算符和条件语句来实现计算器的功能。例如,可以使用if语句判断输入的操作符是加法、减法、乘法还是除法,并根据不同的操作符执行相应的计算操作。 5. 使用绑定机制将计算结果显示在界面上。可以将结果显示框绑定到ViewModel中的一个属性,当计算结果发生变化时,界面会自动更新。 6. 测试计算器的功能,确保各种操作符都能正确计算结果。 综上所述,通过在Xamarin.Forms中使用ViewModel和绑定机制,我们可以实现一个简单的计算器,可以处理各种运算符号,并将结果展示在界面上。以上方法只是其中一种实现方式,您也可以根据自己的需要和喜好进行调整和修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值