计蒜客 加减乘除

本文介绍了一种将中缀表达式转换为后缀表达式并计算其值的算法实现,适用于包含基本算术运算符(加减乘除幂)的表达式。该算法通过优先级比较来处理运算符,确保了计算的准确性。

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

点击打开链接

1000ms     65536K
给出一个表达式,其中运算符仅包含  + , - , * , / , ^ 要求求出表达式的最终值在这里, /  为整除最终结果为正整数,数据保证不需要使用高精度!

输入仅一行,即为表达式。

输出仅一行,既为表达式算出的结果 结果小于 long int 的最大范围,且整个计算的过程中,也不会超过 long int 的最大范围。

表达式总长度 \leq 2020

样例输入
2^3+1
样例输出
9

ac代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<stack>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#define ll long long
using namespace std;

const int maxOp=6;

struct Pri
{
    char ch;
    ll pri;
}lpri[]={{'=',1},{'^',7},{'*',5},{'/',5},{'+',3},{'-',3}},
 rpri[]={{'=',1},{'^',6},{'*',4},{'/',4},{'+',2},{'-',2}};
ll Leftpri(char op)
{
    for(int i=0;i<maxOp;i++)
        if(lpri[i].ch==op)
            return lpri[i].pri;
}

ll Rightpri(char op)
{
    for(int i=0;i<maxOp;i++)
        if(rpri[i].ch==op)
            return rpri[i].pri;
}

bool IsOp(char ch)
{
    if(ch=='^'||ch=='*'||ch=='/'||ch=='+'||ch=='-')
        return true;
    return false;
}

int Precede(char op1,char op2)
{
    int lpri=Leftpri(op1);
    int rpri=Rightpri(op2);
    if(lpri==rpri)
        return 0;
    else if(lpri<rpri)
        return -1;
    else
        return 1;
}
void TransToPostExp(char* exp,char postExp[])
{
    stack<char>opStack;
    opStack.push('=');
    int i=0;
    while(*exp!='\0')
    {
        if(!IsOp(*exp))//不是运算符
        {
            while(*exp>='0'&&*exp<='9')
            {
                postExp[i++]=*exp;
                exp++;
            }
            postExp[i++]='#';
        }
        else
        {
            int cmpPri=Precede(opStack.top(),*exp);
            if(cmpPri==0)
            {
                opStack.pop();
                exp++;
            }
            else if(cmpPri==-1)
            {
                opStack.push(*exp);
                exp++;
            }
            else
            {
                while(Precede(opStack.top(),*exp)==1)
                {
                    postExp[i++]=opStack.top();
                    opStack.pop();
                }
            }
        }
    }
    while(opStack.top()!='=')
    {
        postExp[i++]=opStack.top();
        opStack.pop();
    }
    postExp[i]='\0';
}

void GetTwoFromStack(stack<int>& numStack,int& a,int& b)
{
    a=numStack.top();
    numStack.pop();
    b=numStack.top();
    numStack.pop();
}

ll Calfrompostexp(char* postExp)//计算后缀表达式
{
    stack<int>numStack;
    int a,b,w;
    while(*postExp!='\0')
    {
        switch(*postExp)
        {
        case '#':
            break;
        case '+':
            GetTwoFromStack(numStack,a,b);
            numStack.push(b+a);
            break;
        case '-':
            GetTwoFromStack(numStack,a,b);
            numStack.push(b-a);
            break;
        case '*':
            GetTwoFromStack(numStack,a,b);
            numStack.push(b*a);
            break;
        case '/':
            GetTwoFromStack(numStack,a,b);
            numStack.push(b/a);
            break;
        case '^':
            GetTwoFromStack(numStack,a,b);
            w=pow((double)b,(double)a);
            numStack.push(w);
            break;
        default:
            int n=0;
            while(*postExp >='0' && *postExp<='9')
            {
                n=n*10+(*postExp-'0');
                postExp++;
            }
            numStack.push(n);
            break;
        }
        postExp++;
    }
    return numStack.top();
}
char Exp[50];
char postExp[50];
int main()
{
    while(cin>>Exp)
    {
        TransToPostExp(Exp,postExp);
        cout<<Calfrompostexp(postExp)<<endl;
    }
    return 0;
}


### 牛网华为机试算法题目解析 #### 题目一:矩阵链相乘优化 在处理矩阵链相乘问题时,可以通过动态规划来减少不必要的算量。例如,在给定三个矩阵 A(10×30), B(30×5), C(5×60),可以按照两种方式算 (AB)C 或者 A(BC)[^1]。前者的算复杂度为 \(10 \times 30 \times 5 + 10 \times 5 \times 60 = 4500\) 次乘法操作;而后者则需要 \(30 \times 5 \times 60 + 10 \times 30 \times 60 = 27000\) 次乘法操作。因此选择合适的括号位置能够显著降低运算成本。 #### 题目二:统字符串中的特定字符数量 对于统某个子串在母串中出现次数的问题,可以直接利用 Python 的内置 `count` 方法完成此任务。下面是一个简单的实现例子: ```python str1 = input() str2 = input() print(str1.lower().count(str2.lower())) ``` 上述代码片段展示了如何忽略大小写差异并数指定字符或子串在整个输入字符串内的存在频率[^2]。 #### 题目三:十六进制转十进制整型数值 当涉及到不同基数之间的转换时,标准库提供了便捷的方法来进行此类变换。比如使用 C++ 中的 `std::stoi` 函数可以从字符串形式读取数据,并将其解释成相应类型的值。这里提供了一个基于该技术的小程序用于演示目的: ```cpp #include <iostream> using namespace std; int main(){ string str; cin >> str; cout << stoi(str, nullptr, 16) << endl; } ``` 这段源码实现了从用户那里接收一个表示十六进制数字的字符串作为输入参数,接着输出对应的十进制表现形式的结果[^3]。 #### 题目四:二十四点游戏逻辑设 最后考虑这样一个经典益智类小游戏——即所谓的“二十四点”。它的基本规则是从一副扑克牌里随机抽取四张卡片(假设它们上面标记有介于1到9之间任意正整数),玩家尝试运用加减乘除四种基础算术运算符以及必要的圆括号改变优先级关系使得最终表达式求值得恰好等于24即可获胜[^4]。 以下是解决这个问题的一种可能策略框架: - 枚举所有可能的操作序列; - 对每种情况应用递归回溯搜索找到满足条件的一组解决方案之一。 虽然具体编码细节超出了当前讨论范围之外,但是理解这些概念有助于构建实际应用程序版本的基础架构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值