美文网首页
C++ 实现算数表达式求解

C++ 实现算数表达式求解

作者: leon0514 | 来源:发表于2024-05-09 22:35 被阅读0次

说明

  1. 算数表达式中只有+-*/这些操作
  2. 可以计算浮点数、负数
  3. 小数点前面的0可以省略
  4. 规定表达式以 # 结尾
  • 判断是否为操作符
    非数字和小数点都认为为操作符
bool isOperator(char c)  
{
    return c == '+' || c == '-' || c == '*' || c == '/' || c == ')' || c == '(' || c == '#';
}

  • 操作符优先级判断
符号 + - * / ( ) #
+ > > < < < > >
- > > < < < > >
* > > > > < > >
\ > > > > < > >
( < < < < < =
) > > > > > >
# < < < < < =

数列的符号表示在栈顶的符号,横列的表示从表达式中读取的符号
当栈顶为(时,合法表达式中不可能读取到 #
当栈顶为)时,合法表达式中不可能读取到 (
当栈顶为#时,合法表达式中不可能读取到 )

int getIndex(char theta)   //获取theta所对应的索引
{
    int index = 0;
    switch (theta)
    {
    case '+':
        index = 0;
        break;
    case '-':
        index = 1;
        break;
    case '*':
        index = 2;
        break;
    case '/':
        index = 3;
        break;
    case '(':
        index = 4;
        break;
    case ')':
        index = 5;
        break;
    case '#':
        index = 6;
    default:break;
    }   
    return index;
}

char getPriority(char theta1, char theta2)   //获取theta1与theta2之间的优先级                                                                                                                                    
{
    const char priority[][7] =     //算符间的优先级关系
    {
        { '>','>','<','<','<','>','>' },
        { '>','>','<','<','<','>','>' },
        { '>','>','>','>','<','>','>' },
        { '>','>','>','>','<','>','>' },
        { '<','<','<','<','<','=','0' },
        { '>','>','>','>','0','>','>' },
        { '<','<','<','<','<','0','=' },
    };

    int index1 = getIndex(theta1);
    int index2 = getIndex(theta2);
    return priority[index1][index2];
}

  • 合法性判断
    这里只判断括号是否匹配
bool isValidExpression(const string& expression) 
{                                                                                                                                                               
    stack<char> brackets;
    for (char c : expression) 
    {
        if (c == '(') 
        {
            brackets.push(c);
        } 
        else if (c == ')') 
        {
            if (brackets.empty() || brackets.top() != '(') 
            {
                return false;
            }   
            brackets.pop();
        }   
    }   
    return brackets.empty();
}
  • 在单独的+-前补0
    为了正确处理负数和带符号的正数
std::string addZero(const std::string& input)
{
    std::string result;
    result.reserve(input.size() + input.size() / 2); // 预留足够的空间,避免频繁的重新分配内存

    for (size_t i = 0; i < input.size(); ++i) 
    {
        if ((input[i] == '-' || input[i] == '+') && (i == 0 || input[i - 1] == '(')) {
            result.push_back('0');
        }
        result.push_back(input[i]);
    }
    return result;
}
  • 清洗数据
    分离表达式和数字
// 判断一个字符串能否被转为浮点数
bool isNumber(const std::string& str)
{
    try
    {
        std::stod(str);
    }
    catch (std::exception& e)
    {
        return false;
    }
    return true;

}

bool formatInput(const string& str, std::vector<std::string>& result)
{
    std::string input = addZero(str);
    string num;
    for (auto ch : input)
    {
        if (::isdigit(ch) || ch == '.')
        {
            num += ch;
        }
        else
        {
            if (!num.empty())
            {
                if (!isNumber(num))
                {
                    return false;
                }
                result.push_back(num);
                num.clear();
            }
            result.push_back(string(1, ch));
        }
    }
    if (!num.empty())
    {
        if (!isNumber(num))
        {
            return false;
        }
        result.push_back(num);
        num.clear();
    }
    return true;
}
  • 计算表达式的值
    在计算表达式的值的时候会继续判断该表达式是否合法
  1. 不能连续出现+-*/操作符
  2. 不能除以0
  3. 操作符前后必须有可以运算的数字
bool evaluate(const std::string& input, double& value)
{
    std::vector<std::string> expression;
    bool valid  = formatInput(input, expression);
    if (!valid) return false;
    std::stack<char> operators;
    std::stack<double> operands;
    operators.push('#');
    for (int i = 0; i < expression.size();)
    {
        auto exp = expression[i];
        if (!isOperator(exp[0]))
        {
            operands.push(std::stod(exp));
            i++;
        }
        else
        {
            char c = exp[0];
            switch (getPriority(operators.top(), c))   //获取运算符栈opter栈顶元素与c之间的优先级,用'>','<','='表示
            {
            case '<':               //<则将c入栈opter
            {
                operators.push(c);
                i++;
                break;
            }
            case '=':               //=将opter栈顶元素弹出,用于括号的处理
            {
                operators.pop();
                i++;
                break;
            }
            case '>':               //>则计算
            {
                if (operands.empty()) return false;
                char theta = operators.top();
                operators.pop();
                double a = operands.top();
                operands.pop();
                if (operands.empty()) return false;
                double b = operands.top();
                operands.pop();
                if (theta == '/' && a == 0) return false;
                operands.push(calculate(b, theta, a));
                break;
            }
            case '0':
            {
                return false;
            }
            }
        }
    }
    // 数字栈中不存在数字,无法计算,返回法false
    if (operands.empty()) return false;
    value = operands.top();
    return true;
}

相关文章

  • 1.1tensorflow基础

    行为主义:基于控制理论,构建感知-动作控制系统; 符号主义:基于算数逻辑表达式,求解问题时候,先将问题抽象成表达式...

  • 分治策略

    求解递归式方法 最大子数组问题 分治策略 分治法流程 伪代码 C++实现 线性解 流程 代入法求解递归式 递归树法...

  • 四则运算表达式求值

    利用栈求解四则运算:求解思路为先将中缀表达式转换为后缀表达式,再利用后缀表达式求解中缀表达式:运算符出现在两个数字...

  • 第三章 数据处理(4)c++算数运算符

    (四)c++算数运算符 1.算数运算符 c++一共有五种基本的算数运算符,+, -, *, /, %分别是加减乘...

  • 滴滴校招-寻找丑数-c++

    面试题之丑数的C++实现求解(孤陋寡闻了,才知道丑数这么high的东东)

  • FM

    因子分解机 1、功能:求解高维且稀疏的交叉特征的权重。 2、表达式及求解: 原始表达式: 直接求解的困难:是高维的...

  • 算法 | 解析算法

    【算法思想】 找出问题的条件与结果之间的数学表达式,再通过表达式的计算来实现问题求解。 【算法实例】 输入已知三角...

  • 求解数独的C++实现

    求解数独的C++实现## 动机### 在做数独的时候,抱着好奇心想做一个数独求解的程序。当时我并没有接触多少算法,...

  • SPSS数据分析从零开始(2):变量赋值

    1、常用基本概念 在变量赋值中汇涉及算数表达式、函数、条件表达式等基本概念。 1)算数表达式 参与运算的数据类型和...

  • 第七章 示例说明(重要)

    前面是理论部分,这里是实践 示例:表达式求值 实现简单算数表达式的求值器 类型断言 类型断言是一个使用在接口值上的...

网友评论

      本文标题:C++ 实现算数表达式求解

      本文链接:https://www.haomeiwen.com/subject/vhhwxjtx.html