高级计算器

输入方法:复制你想计算的内容运行程序后自动计算

#include <iostream>
#include <Windows.h>
#include <string>
#include <math.h>
#include<cstdio>  
#include<stack>  
#include<string>  
#include<cstring>  
#include<cmath>  
#include<ctype.h>  
#pragma warning(disable:4996)
using namespace std;
string Return_the_content_of_the_clipboard() {
    HANDLE hData = GetClipboardData(CF_TEXT); // 获取剪切板数据句柄
    char* pszText = static_cast<char*>(GlobalLock(hData)); // 锁定内存并获取指向数据的指针
    GlobalUnlock(hData); // 解锁内存
    CloseClipboard(); // 关闭剪切板
    string s1 = pszText;
    return s1;
}

int OperatorPri(char opt)//将优先级量化便于比较 
{
    switch (opt)
    {
    case '#':  return 0;
    case ')':  return 1;
    case '|':
    case '&':  return 2;
    case '-':
    case '+':  return 3;
    case '*':
    case '/':  return 4;
    case '!':  return 5;
    case '(':  return 6;
    default: return -1;
    }
}

int PreOrder(char opt1, char opt2)//比较两个运算符的优先级 
{
    int i = OperatorPri(opt1);
    int j = OperatorPri(opt2);
    if (opt2 == '(')    //( )内的 + - * / 还能进栈但是 + - * / 对应的数字小于 ( 对应的数字 所以把这里设置成 1 让()内的 + - * / 可以进栈 
        return 1;
    if (i == -1 || j == -1)
        return -1;
    if (i > j)
        return 1;
    else if (i == j)
        return 0;
    else
        return -1;
}

bool isOpr(char* p)   //判断运算公式中的字符是不是数字 
{
    if (*p >= '0' && *p <= '9')
        return true;
    else return false;
}

char* getNum(char* p, int& num)//将char型字符换成数字 
{
    num = 0;
    while (isOpr(p))
    {
        num = 10 * num + (*p - '0');
        p++;
    }
    p--;     //为了防止后面while循环中的p++跳过了运算符 !!!!!!!!! 
    return p;

}

int express(int e1, int e2, char opt)   //运算
{
    cout << e1 << opt << e2 << " is calculated!" << endl;
    switch (opt)
    {
    case '+': return e1 + e2;
    case '-': return e1 - e2;
    case '*': return e1 * e2;
    case '/': return e1 / e2;
    case '&': return e1 && e2;
    case '|': return e1 || e2;
    case '!':return !e2;   //逻辑非运算符是单目运算符要进行特殊处理(仅进行一个数的运算,另外一个出栈的数据在重新入栈)
    default: cout << "wrong" << endl;
    }
}

int Calc(char* s)
{
    int x;     //用来储存 express(e1,e2,opt) 要不然输出两边 cout<<e1<< opt <<e2<<" is calculated!"<<endl;
    bool flag = false;  //要用来判断最终两个栈是否为空 
    stack<char> opt;  //用来储存运算符的栈 
    char c;     //用来保存  get_top()数据 
    stack<int> opr;   //用来储存数字的栈 
    int e1, e2, e;   //用来保存 get_top   e 用来压入数据 
    opt.push('#');
    opr.push(1);  //为了防止第一个运算符便是逻辑非(!运算符采用出栈两个数据进行一个数据的运算,另外一个重新入栈,这样便保持了单目运算符和双目运算符的一致性,而刚开始数据栈里面先储存个1,便是为了防止第一个运算符便是!的情况,1不参与任何的运算)
    char* p = s;   //初始化p 
    while (*p != '#')
    {
        if (isOpr(p))  //把字符转化为数字并入数字栈
        {
            p = getNum(p, e);
            opr.push(e);
        }
        else      //如果不是数字而是运算符,则对此运算符和栈顶运算符的优先级进行比较  
        {
            c = opt.top();
            if (PreOrder(*p, c) > 0) //当前入栈的运算符比栈顶的运算符优先级高则入栈  
            {
                opt.push(*p);
            }
            else      //当前入栈的运算符比栈顶的运算符优先级低则栈顶运算符出栈并出栈两个数据进行计算  
            {
                opt.pop();
                e1 = opr.top();
                opr.pop();
                e2 = opr.top();
                opr.pop();
                x = express(e2, e1, c);
                if (c == '!')   //若是逻辑非运算符,则只需要一个数据参与运算,另外一个数据再入栈
                {
                    opr.push(e2);
                }

                opr.push(x);  //结果入栈
                if (*p == '+' || *p == '-' || *p == '*' || *p == '/' || *p == '&' || *p == '|' || *p == '!')  //在进行了一次数据和运算符出栈计算后,*p对应的那个运算符还要继续进栈 
                {
                    opt.push(*p);
                }
                if (*p == ')')
                {
                    c = opt.top(); //先判断这是否是个空括号 
                    if (c != '(')
                    {
                        c = opt.top();
                        opt.pop();
                        e1 = opr.top();
                        opr.pop();
                        e2 = opr.top();
                        opr.pop();
                        x = express(e2, e1, c);
                        if (c == '!')
                        {
                            opr.push(e2);
                        }
                        opr.push(x);
                        c = opt.top();
                        opt.pop();
                    }
                    else
                    {
                        opt.pop();
                    }
                }
            }

        }
        p++;
    }
    if (*p == '#')
    {
        c = opt.top();
        opt.pop();
        e1 = opr.top();
        opr.pop();
        e2 = opr.top();
        opr.pop();
        x = express(e2, e1, c);
        if (c == '!')
        {
            opr.push(e2);
        }
        opr.push(x);
        c = opt.top();
        opt.pop();
        while (c != '#')
        {
            e1 = opr.top();
            opr.pop();
            e2 = opr.top();
            opr.pop();
            x = express(e2, e1, c);
            if (c == '!')
            {
                opr.push(e2);
            }
            opr.push(x);

            c = opt.top();
            opt.pop();
        }
        e = opr.top();//最终结果
        opr.pop();
        cout << "结果:" << e << endl;
        if (opt.empty() && opr.size() == 1) //数据栈中还有一个'1'没出栈  
            flag = true;
        if (flag)
            return e;
        else
            return -1;
    }

}
int main()
{
    string s1 = Return_the_content_of_the_clipboard();
    char mychar[100] = {};
    for (int i = 0; i < 100; i++)mychar[i] = s1[i];
    cout << Calc(mychar) << endl;
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小唐C++

干累了,给个吧,求求了

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值