表达式计算题型思路

发布于:2022-07-27 ⋅ 阅读:(428) ⋅ 点赞:(0)

例1: 表达式计算4

题目注意点:

  • 出现多余括号时,由于多余括号的可察性(唯一性),我们发现多余括号不可能在中间出现,所以多余括号的位置仅有三种情况(可以叠加):
    1.多余括号在左侧出现
    2.多余括号在右侧出现
    3.多余括号恰好成对出现在最两端
  • 能够应对负数情况
  • 读入字符串,但是要输出数字

题目思路:

  • 通过不断寻找最后一次运算(即运算的最后一步),来递归实现全局运算
  • 注意这个最后一次运算肯定不能被括号羁绊,因此在递归开始时,我们要统计括号数量,时刻优化运算式子,来确保运算顺利进行
  • 要妥善安排递归中运算符处理顺序
  • 可以手写样例测试,增加一A率

ac代码:

#include<bits/stdc++.h>
using namespace std;
string s;
int mypow(int a, int b)
{
    int ans =1;
    while(b)
    {
        if(b & 1) ans *= a;
        a *= a; b >>= 1;
    }
    return ans;
}
int change(int l, int r)
{
    int x = 0;
    for(int i = l; i <= r; i++)
        x = x*10 + s[i] - '0';
    return x;
}//字符串->整数 
int deal(int l, int r)
{
    //找最后一次运算
    int cnt = 0;//左边还没有消掉的(的个数
    int pos1 = -1, pos2 = -1, pos3  =-1;//三类运算 
    for(int i= l; i<= r; i++)
    {
       if(s[i] == '(') cnt++;
       if(s[i] == ')') cnt--;
       if (cnt == 0)
       {
           if (s[i] == '+' || s[i] == '-') pos1 = i;
           if (s[i] == '*' || s[i] == '/') pos2 = i;
           if (s[i] == '^' ) pos3 = i;
       }
    }
    //丢掉多余的括号
    if (cnt > 0 && s[l] =='(') return deal(l+1, r);
    if (cnt < 0 && s[r] ==')') return deal(l, r-1);
    //丢掉两端成对的括号
    if (s[l] =='(' && s[r] ==')' && pos1+pos2+pos3 == -3)return deal(l+1, r-1); 
    //分符号左边右边计算
    if(pos1 != -1)
        if (s[pos1] == '+')return  deal(l, pos1-1) + deal(pos1+1, r);
        else return  deal(l, pos1-1) - deal(pos1+1, r);     
    if(pos2 != -1)
        if (s[pos2] == '*')return  deal(l, pos2-1) * deal(pos2+1, r);
        else return  deal(l, pos2-1) / deal(pos2+1, r);    
    if(pos3 != -1)
        return  mypow(deal(l, pos3-1),deal(pos3+1, r));    
        
    return change(l, r);
}
int main()
{
    cin>>s;
    cout << deal(0, s.length()-1) << endl;
    return 0;
}

例2:最长合法括号序列
在这里插入图片描述

借鉴思路:最长合法括号序列

栈+dp

  • f [ i ] f[i] f[i]表示到位置 i i i能够形成的最长合法括号序列的子串的长度
  • i i i为正在处理右括号,栈顶为k(k>0),则有状态转移方程: f [ i ] = f [ k − 1 ] + i − k + 1 f[i]=f[k-1]+i-k+1 f[i]=f[k1]+ik+1

核心代码:

scanf("%s",c+1); n=strlen(c+1);
for(int i=1;i<=n;i++){
    if(c[i]=='(') S.push(i);
    else if(!S.empty()){
        f[i]=f[S.top()-1]+i-S.top()+1;//转移方程
        mx=max(mx,f[i]);
        S.pop();
    }
}
for(int i=1;i<=n;i++)if(f[i]==mx)ans++;

样例模拟:
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到