Tiny_python(基础数学)

Tiny_python(基础数学)

基础的数学运算

前言:本来打算做科学计算器的,但是看到B站已经有了现成的了。决定做Python(毕竟也算计算器)

本期实现:

  1. 加减乘除
  2. 括号分析
  3. 基础变量实现
  4. Python 输出样式

大量使用了堆的容器。没什么高的技术含量,主要是转化成后缀表达式(逆波兰表达式挺有含金量)

后缀表达式(逆波兰表达式)

直接上图和视频
计算部分
转化部分

v0.1源代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

stack operators;
stack temp_suffix_result;
unordered_map variables; // Global container for variables

typedef struct symbol
{
    string name;
    string data;
    int typ;
    int pri;
    int pos;
    double val;
} SYMBOL;

/*
移除字符串中的空格
*/
string remove_spaces(string *str)
{
    str->erase(std::remove(str->begin(), str->end(), ' '), str->end());
    return *str;
}

/*
优先级map
*/
std::unordered_map precedence = {
    {'+', 1},
    {'-', 1},
    {'*', 2},
    {'/', 2},
    {'^', 3}};

/*
处理操作符
*/
void process_operator(char op, std::stack &operators, std::stack &temp_suffix_result)
{
    while (!operators.empty() && operators.top() != "(" &&
           precedence[operators.top()[0]] >= precedence[op])
    {
        temp_suffix_result.push(operators.top());
        operators.pop();
    }
    operators.push(std::string(1, op));
}

/*
优化原始表达式,方便转化为逆波兰表达式
*/
void Expression_optimization(string *str)
{

    std::regex pattern("\\*\\*"); // 正则表达式中需要转义的字符
    std::string replacement = "^";

    // 使用 std::regex_replace 进行替换
    *str = std::regex_replace(*str, pattern, replacement);
    /*在单独的负数,负号前面插入0*/
    for (int i = 0; i < str->size(); i++)
    {
        if (str->at(i) == '-' && (i == 0 || str->at(i - 1) == '('))
        {
            str->insert(i, "0");
        }
    }
}

void lexer(string *str)
{
    remove_spaces(str);
    int i = 0;
    bool lastWasOperatorOrOpenParenthesis = true; // 用于跟踪上一个字符是否为操作符或 '('

    while (i < str->size())
    {
        char current = str->at(i);

        if (isdigit(current))
        { // 处理连续的数字
            std::string temp;
            while (i < str->size() && (isdigit(str->at(i)) || str->at(i) == '.'))
            {
                temp.push_back(str->at(i));
                i++;
            }
            temp_suffix_result.push(temp);
            lastWasOperatorOrOpenParenthesis = false;
        }
        else if (isalpha(current))
        { // 处理变量名
            std::string temp;
            while (i < str->size() && isalpha(str->at(i)))
            {
                temp.push_back(str->at(i));
                i++;
            }
            temp_suffix_result.push(temp);
            lastWasOperatorOrOpenParenthesis = false;
        }
        else if (current == '(')
        {
            operators.push("(");
            lastWasOperatorOrOpenParenthesis = true;
            i++;
        }
        else if (current == ')')
        {
            while (!operators.empty() && operators.top() != "(")
            {
                temp_suffix_result.push(operators.top());
                operators.pop();
            }
            if (!operators.empty()) operators.pop(); // 移除开括号
            lastWasOperatorOrOpenParenthesis = false;
            i++;
        }
        else if (precedence.find(current) != precedence.end())
        { // 处理操作符
            if (lastWasOperatorOrOpenParenthesis)
            {
                if (current == '-')
                {
                    temp_suffix_result.push("0"); // 在负号前加一个零
                }
                else
                {
                    throw std::invalid_argument("无效的操作符位置");
                }
            }
            process_operator(current, operators, temp_suffix_result);
            lastWasOperatorOrOpenParenthesis = false;
            i++;
        }
        else
        {
            throw std::invalid_argument("无效的字符: " + std::string(1, current));
        }
    }

    while (!operators.empty())
    {
        temp_suffix_result.push(operators.top());
        operators.pop();
    }
}

void clear_stack(stack &s, stack &o)
{
    stack empty;
    s.swap(empty);
    stack empty2;
    o.swap(empty2);
}

// 定义函数类型
using OperatorFunc = std::function;

// 定义操作函数
double add(double left, double right) { return left + right; }
double subtract(double left, double right) { return left - right; }
double multiply(double left, double right) { return left * right; }
double divide(double left, double right) { return left / right; }
double power(double left, double right) { return std::pow(left, right); }

// 操作符映射表
std::unordered_map operatorMap = {
    {"+", add},
    {"-", subtract},
    {"*", multiply},
    {"/", divide},
    {"^", power}};

double Binary_Computing_Executor(double left, double right, const std::string op)
{
    auto it = operatorMap.find(op);
    if (it != operatorMap.end())
    {
        return it->second(left, right);
    }
    clear_stack(temp_suffix_result, operators);
    throw std::invalid_argument("未知的运算符: " + op);
}

double calculate(string *str, stack temp_suffix_result)
{
    std::stack temp_resulet, temp_suffix;

    while (!temp_suffix_result.empty())
    {
        temp_suffix.push(temp_suffix_result.top());
        temp_suffix_result.pop();
    }

    while (!temp_suffix.empty())
    {
        std::string current = temp_suffix.top();
        temp_suffix.pop();

        if (isdigit(current[0]))
        {
            temp_resulet.push(current);
        }
        else if (isalpha(current[0]))
        { // Handle variable usage
            if (variables.find(current) != variables.end())
            {
                temp_resulet.push(std::to_string(variables[current]));
            }
            else
            {
                clear_stack(temp_suffix_result, operators);
                throw std::invalid_argument("变量 " + current + "未定义.");
            }
        }
        else
        {
            if (temp_resulet.size() < 2)
            {
                clear_stack(temp_suffix_result, operators);
                throw std::invalid_argument("无效的表达式");
            }
            double right = std::stod(temp_resulet.top());
            temp_resulet.pop();
            double left = std::stod(temp_resulet.top());
            temp_resulet.pop();
            double result = Binary_Computing_Executor(left, right, current);
            temp_resulet.push(std::to_string(result));
        }
    }

    if (temp_resulet.size() != 1)
    {
        clear_stack(temp_suffix_result, operators);
        throw std::invalid_argument("无效的表达式");
    }

    return std::stod(temp_resulet.top());
}

void executer(string *str, SYMBOL *var)
{
    Expression_optimization(str);

    size_t equal_pos = str->find('=');
    if (equal_pos != string::npos)
    {
        string var_name = str->substr(0, equal_pos);
        if (isdigit(var_name[0]))
        {
            clear_stack(temp_suffix_result, operators);
            throw std::invalid_argument("变量名不能以数字开头.");
        }
        string expression = str->substr(equal_pos + 1);
        lexer(&expression);
        double result = calculate(&expression, temp_suffix_result);
        variables[var_name] = result;
        std::cout << var_name << " = " << result << std::endl;
    }
    else
    {
        lexer(str);
        double result = calculate(str, temp_suffix_result);
        std::cout << result << std::endl;
    }

    std::stack empty;
    temp_suffix_result.swap(empty);
    std::stack empty2;
    operators.swap(empty2);
}

int main()
{
    bool flag = 0;
    string input_str;
    while (1)
    {
        clear_stack(temp_suffix_result, operators);
        if (!flag)
            cout << ">>> ";
        else
            flag = 0;
        getline(cin, input_str);
        if (input_str.empty())
        {
            flag = 1;
            cout << ">>> ";
            continue;
        }
        if (input_str == "exit")
            break;
        SYMBOL var;
        try
        {
            executer(&input_str, &var);
        }
        catch (const std::invalid_argument &e)
        {

            std::cerr << e.what() << std::endl;
        }
    }

    return 0;
}

暂无评论

发送评论 编辑评论

|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇