简单实现计算器(数据结构)

文章转载自:https://blog.csdn.net/gebushuaidanhenhuai/article/details/62932960

要想实现计算器,我们可以首先把中缀表达式转化为后缀表达式,再计算中缀表达式的值。

具体的理论分析请查看:http://blog.csdn.net/gebushuaidanhenhuai/article/details/62948774

#include<iostream>
#include<stack>
#include<cstring> 
using namespace std;
// 首先把中缀表达式转化为后缀表达式

//定义优先级
int Priority(char ch)
{
    int i = 0;
    switch (ch)
    {
    case'(':
    {
               i = 1;
               break;
    }
    case'+':
    {
               i = 2;
               break;
    }
    case'-':
    {
               i = 2;
               break;
    }
    case'*':
    {
               i = 3;
               break;
    }
    case'/':
    {
               i = 3;
               break;
    }
    case')':
    {
               i = 4;
               break;
    }
    default:
    {
               i = -1;
               break;
    }
    }
    return i;
}
//将中缀表达式变为后缀表达式
// 借助一个栈S 用来存放操作符
//一个数组用来存放后缀表达式
void  Tonibolan(char* ch, char* arr)
{
    stack <char> s; // 借助一个栈S 用来存放操作符
    int i = 0;
    while (*ch != '\0')
    {
        if (*ch >='0'&&*ch<='9')
        {
            arr[i++] = *ch;
        }
        else if (*ch=='(') // 左括号直接入栈
        {
            s.push(*ch);
        }
        else if (*ch == ')')  // 右括号从操作符栈弹出操作符,直到弹出‘)';
        {
            while (s.top() != '(')
            {
                arr[i++] = s.top();// 把操作符弹出到存有后缀表达式的数组里
                s.pop();
            }
            if (s.top() == '(')
            {
                s.pop();  //后缀表达式没有'('  ,   ')'
            }
        }

        // 存有操作符的栈为空或者 取出来的操作符的优先级 大于 栈顶操作符的优先级 直接入栈
        else if (s.empty() || Priority(*ch) > Priority(s.top()))
        {
            s.push(*ch);
        }

        // 取出来的操作符A   优先级小于等于操作符栈   栈顶的优先级。
        //把栈顶的操作符Pop出栈,放到后缀表达式的数组里,直到A的优先级大于栈顶 操作符的优先级 ,A入操作符栈
        else
        {
            while (Priority(*ch) <= Priority(s.top()))
            {
                arr[i++] = s.top();
                s.pop();
                if (s.empty())
                {
                    break;
                }
            }
            s.push(*ch);
        }
        ++ch;
    }
    while (!s.empty())
    {
        arr[i++] = s.top();
        s.pop();
    }
}

//计算后缀表达式
//遍历储存后缀表达式的列表,将元素依次进栈,当遇到操作符时,
//连续出栈两个元素,进行运算,再将结果进栈,最后栈内留下的元素就是计算结果
int Calcval(char* ret)
{
    stack<char> st;
    //遍历后缀表达式
    while (*ret != '\0')  
    {
        if (*ret >= '0'&&*ret <='9')  //若果是数字直接入栈
        {
            st.push(*ret);
        }
        else
        {
            //遇到操作符,连续出栈两个元素,进行运算,在将结果入栈
            switch (*ret)
            {
            case'+':
            {
                       char a = st.top();
                       st.pop();
                       char b = st.top();
                       st.pop();
                       st.push(((a - '0') + (b - '0')) + '0');
                       break;
            }

            case'-':
            {
                       char a = st.top();
                       st.pop();
                       char b = st.top();
                       st.pop();
                       st.push(((b - '0') - (a - '0')) + '0');
                       break;
            }
            case'*':
            {
                       char a = st.top();
                       st.pop();
                       char b = st.top();
                       st.pop();
                       st.push(((b - '0') * (a - '0')) + '0');
                       break;
            }

            case'/':
                {
                       char a = st.top();
                       st.pop();
                       char b = st.top();
                       st.pop();
                       if (a != '0')
                       {
                           st.push(((b - '0') / (a - '0')) + '0');
                       }
                       else
                       {
                           cout << "除数不能为0!" << endl;
                       }
                       break;
                }
            default:
                {
                    break;
                }
            }
        }
        ++ret;
    }
    return st.top() - '0';     //栈里面的数据就是最后的结果
}

void Test()
{
    char ret[100] = { 0 };
    char arr[100] = { 0 };
    cout << "请输入要计算的表达式:" << endl;
    cin.get(arr, 100);

    Tonibolan(arr, ret);

    int len = strlen(ret);
    int i = 0;
    cout << "算式的逆波兰表达式为:" << endl;
    while (len--)
    {
        cout << ret[i++]<<" ";
    }
    cout << "\n算式的计算结果为:" << endl;
    cout << Calcval(ret) << endl;
}
    int main()
    {
        Test();
        return 0;
    }



猜你喜欢

转载自blog.csdn.net/weixin_41969587/article/details/82720066