224. 基本计算器 | 43.字符串相乘

文章介绍了如何使用栈来实现一个基本的计算器,处理字符串表达式的加减乘除运算,以及处理括号内的递归计算。同时,提供了模拟乘法的方法来计算两个字符串形式的非负整数的乘积,避免使用内置的大整数库或直接转换为整数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

224. 基本计算器

给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。

注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval()

示例 1:

输入:s = "1 + 1"

输出:2

示例 2:

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

输出:3

示例 3:

输入:s = "(1+(4+5+2)-3)+(6+8)"

输出:23

提示:

  • 1 <= s.length <= 3 * 105

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

  • s 表示一个有效的表达式

  • '+' 不能用作一元运算(例如, "+1" 和 "+(2 + 3)" 无效)

  • '-' 可以用作一元运算(即 "-1" 和 "-(2 + 3)" 是有效的)

  • 输入中不存在两个连续的操作符

  • 每个数字和运行的计算将适合于一个有符号的 32位 整数

如何实现一个计算器 :: labuladong的算法小抄 (gitee.io)

思路:栈

当i遇到运算符时,将前一个num和sign入栈,然后再更新sign为当前运算符,num为0。

这里还额外实现了'*'、'/',为了做到先乘除后加减:

'+'、'-' 运算符只能给栈内push值,而'*'、'/' 运算符可以从栈内pop出被乘数或被除数,再将乘除运算后的结果push入栈内。

class Solution {
public:
    int calculate(string s)
    {
        int index=0;
        return deal(s,index);
    }
    int deal(string& s,int& i) //注意:传入i的引用
    {
        stack<int> st;
        int num=0;
        char sign='+';//记录num前的符号,默认为'+'
        for(;i<s.size();i++)
        {
            char c=s[i];
            if(c=='(')//遇到左括号,开始递归,求(...)算出的值
            {
                num=deal(s,++i);//因为传入的是i的引用,所以递归调用结束后,i此时就是与该'('对应的')'的下标
            }
            if(isdigit(c))
            {
                num=num*10+(c-'0');
            }
            if((!isdigit(c)&&c!=' ')||i==s.size()-1)//遇到运算符或者来到字符串末尾,将前一个num和sign入栈(跳过' ')
            {
                int temp=0;
                switch(sign)//前一个num的符号
                {
                    case '+':
                        st.push(num);
                        break;
                    case '-':
                        st.push(-num);
                        break;
                    case '*':
                        temp=st.top();
                        st.pop();
                        st.push(temp*num);
                        break;
                    case '/':
                        temp=st.top();
                        st.pop();
                        st.push(temp/num);
                        break;
                }
                sign=c;//更新当前num的符号
                num=0;//更新num的值
            }
            if(c==')')//遇到右括号,结束递归
                break;
        }
        int res=0;
        while(!st.empty())//栈内所有的元素之和即为表达式之值
        {
            res+=st.top();
            st.pop();
        }
        return res;
    }
};
43. 字符串相乘

给定两个以字符串形式表示的非负整数 num1num2,返回 num1num2 的乘积,它们的乘积也表示为字符串形式。

注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。

示例 1:

输入: num1 = "2", num2 = "3"

输出: "6"

示例 2:

输入: num1 = "123", num2 = "456"

输出: "56088"

提示:

  • 1 <= num1.length, num2.length <= 200

  • num1 和 num2 只能由数字组成。

  • num1 和 num2 都不包含任何前导零,除了数字0本身。

思路:模拟乘法

下图为原始的乘法:

将其做改进:

注意:num1[i] 和 num2[j] 的乘积对应的就是 res[i+j] 和 res[i+j+1] 这两个位置。

class Solution {
public:
    string multiply(string num1, string num2) {
        if(num1=="0"||num2=="0")
            return "0";
        int m=num1.size();
        int n=num2.size();
        vector<int> res(m+n,0);//最大是m+n位
        string ans;
        for(int i=m-1;i>=0;i--)
        {
            for(int j=n-1;j>=0;j--)
            {
                int p=i+j;//乘积在res中的下标位置
                int q=i+j+1;
                int mul=(num1[i]-'0')*(num2[j]-'0');
                int cur=mul+res[q];//当前的乘积,叠加到res上
                res[q]=cur%10;//后一位存的永远是0-9
                res[p]+=cur/10;//前一位用+=保存进位 
            }
        }
        int index=0;
        //去掉前导0
        for(int i=0;i<m+n;i++) {
            if(res[i]!=0) {
                index=i;
                break;
            }
        }
        for(int i=index;i<m+n;i++)
        {
            ans+=to_string(res[i]);
        }
        return ans;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值