计算器测试用

// ConsoleApplication2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <cmath>
#include <unordered_map>
#include <unordered_set>
#include <string>
#include <iostream>
#include <set>
#include<vector>
#include <stack>
#include <queue>
#include <list>


typedef float (*fun_sin)(float);
static     std::unordered_map<std::string, fun_sin> one_arg = {
    { "sin",sin },
    { "cos",cos },
    { "tan",tan },
    { "tan",tan },
    { "sqrt",sqrt },
    { "pow", sqrt },
};

int priority(const std::string& oper1, const std::string& oper2)
{
    static  std::unordered_map<std::string, int> priorityMap = {
        { "+",1 },
        { "-",1 },
        { "*",2 },
        { "/",2 },
        { "(",3 },
        { ")",3 },
    };     
    return priorityMap[oper1] - priorityMap[oper2];
}
bool isNumber(const std::string& str)
{
    for (auto c : str)
    {
        if ((c >= '0' && c <= '9') || c == '.')
        {

        }
        else
        {
            return false;
        }
    }
    return true;
}
bool isOperator(const std::string& str)
{
    static  std::unordered_set<std::string> operatorSet = {
        "+",
        "-",
        "*",
        "/",
        "(",
        ")",
        ","
    };
    return operatorSet.count(str) > 0;
}
bool isFuction(const std::string& str)
{

return one_arg.count(str) > 0;
}
std::vector<std::string> split(const std::string& str, const std::string& sep)
{
    //pow(2,3*(40+51))+33*(488+a005)*
    std::vector<std::string> ret;
    int start = 0;

    while (start < str.size())
    {
        int index = str.find(sep, start);
        if (index < 0)
        {
            index = str.size();
            ret.push_back(str.substr(start, index - start));
            break;
        }
        else
        {
            ret.push_back(str.substr(start, index - start));
            ret.push_back(sep);
        }
        start = index + sep.length();

    }

    return ret;

}

std::vector<std::string> split(const std::string& str, const std::vector<std::string>& seps)
{
    std::list<std::string> retList;
    std::vector<std::string> retVector;
    retList.push_back(str);
    for (auto spe : seps)
    {
        int size = retList.size();
        for (int i = 0; i < size; i++)
        {
            auto item = retList.front();
            auto parts = split(item, spe);
            retList.pop_front();
            for (auto& part : parts)
            {
                if (part.empty())
                    continue;
                retList.push_back(std::move(part));
            }
        }
    }
    retVector.assign(retList.begin(), retList.end());
    return retVector;
}
std::list<std::string> infixToSuffix(const std::vector<std::string> & exp)
{
    //2*sqrt(33*(488+005))+3
    std::stack<std::string> operatorStack;
    std::list<std::string> dataStack;
    std::stack<std::string> fuctionStack;
    for (int i = 0; i < exp.size(); ++i)
    {

        if (isOperator(exp[i]))
        {
            if (exp[i] == ")")
            {
                while (operatorStack.size()>0 && operatorStack.top() != "(")
                {
                    dataStack.push_back(operatorStack.top());
                    operatorStack.pop();
                }
                if (operatorStack.size() <= 0 || operatorStack.top() != "(")
                {
                    std::cout << "括号不匹配:"  << std::endl;
                    return {};
                    
                }
                operatorStack.pop();
                if (isFuction(operatorStack.top()))
                {
                    dataStack.push_back(operatorStack.top());
                    operatorStack.pop();
                }

                continue;
            }
            if (operatorStack.empty() || operatorStack.top() == "("
                || priority(operatorStack.top(), exp[i]) < 0)
                operatorStack.push(exp[i]);
            else
            {
                dataStack.push_back(operatorStack.top());
                operatorStack.pop();
                operatorStack.push(exp[i]);
                
            }
            
        }
        else if (isNumber(exp[i]))
        {
            dataStack.push_back(exp[i]);
        }
        else if (isFuction(exp[i]))
        {
            operatorStack.push(exp[i]);
        }
        else
        {
            std::cout << "未知的符号:"<< exp[i] <<std::endl;
            return{};
        }

    }
    while (operatorStack.size() > 0)
    {
        dataStack.push_back(operatorStack.top());
        operatorStack.pop();
    }
    return dataStack;
}
double   calculate(double d1, double d2, char oper)
{
    switch (oper)
    {
    case '+':
        return d1 + d2;
    case '-':
        return d1 - d2;
    case '*':
        return d1 * d2;
    case '/':
        return d1 / d2;
    default:
        std::cout << "不是操作符" << std::endl;
        break;
    }
}

double complute(std::string expression)
{
    //第一步,  按符号切割字符串,变成中缀表达式
    //第二步, 中缀表达式转后缀表达式
    std::vector<std::string> opers = {
        "*",
        "/",
        "+",
        "-",
        "(",
        ")",
        ",",
    };

    auto infixExpression = split(expression, opers);
    auto suffixExpression = infixToSuffix(infixExpression);

    std::vector<double> ret;
    for (auto& item : suffixExpression)
    {
        if (isNumber(item))
        {
            ret.push_back(std::stod(item));
        }
        else if (isOperator(item))
        {
            double d2 = ret.back();
            ret.pop_back();
            double d1 = ret.back();
            ret.pop_back();
            ret.push_back(calculate(d1, d2, item.front()));
        }
        else if (isFuction(item))
        {
            double d1 = ret.back();
            ret.pop_back();
            ret.push_back(one_arg[item](d1));
        }
        else
        {
            std::cout << "未知的符号:" << item << std::endl;
        }
    }
    return ret.back();
}
int main()
{

    //auto a = one_arg["sin"](1);
    //auto b = one_arg["cos"](1);
    //auto c = one_arg["tan"](1);
    //auto d = one_arg["sqrt"](2);

    std::string expression = "sqrt(sqrt(2)+3*5)*sqrt(33*(488+005))*3";
    auto d = complute(expression);
    auto d2 = sqrt(sqrt(2) + 3 * 5)*sqrt(33 * (488 + 005)) * 3;
    while (true)
    {
        std::cout << ">>>";
        std::string line;
        std::getline(std::cin, line);
    }
    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值