C++桌面计算器

C/C++ 专栏收录该内容
17 篇文章 0 订阅

思路:输入一个字符串,首先找到等号将其分为左右两部分,左部分为变量,右部分为运算式,分别处理。

           对于左边部分,直接记录下来变量名最后输出即可。

           右边部分,是一个算术表达式。首先将其由中缀表达式变为后缀表达式,然后对后缀表达式求值即可。在求值过程中会有一些变量,我们利用map保存变量名对应的值即可。

参考资料:解析算术表达式[1]后缀式(逆波兰式)   http://blueve.me/archives/318

                  调度场算法(中缀变后缀)  http://zh.wikipedia.org/wiki/Shunting_yard%E7%AE%97%E6%B3%95

                  map的有关用法

存在问题:1.不能处理浮点数

                  2.不能处理负数

附上源码:

#include<iostream>
#include<string>
#include<map>
#include<cstdio>
using namespace std;

bool compare(char a,char b)//比较a与b的优先级
{
    int preference[100];
    preference['+'] = 1;
    preference['-'] = 1;
    preference['*'] = 2;
    preference['/'] = 2;
    preference['('] = 3;
    if(preference[a] > preference[b])
        return true;
    return false;
}

int operation(int x,int y,char z)
{
    switch(z)
        {
            case '+':
                return x+y;
            case '-':
                return x-y;
            case '*':
                return x*y;
            case '/':
                return x/y;
        }
}

int main()
{
    freopen("in.txt","r",stdin);
    int i,j,k;
    map <char,int>my_map;
    string whole_string;
    while(cin >> whole_string)
    {
        int split;
        for(i=0;i<whole_string.size();i++)
            if(whole_string[i] == '=')
            {
                split = i;
                break;
            }
        //从split+1到最后都为算术表达式

        int length = whole_string.size()-split-1;//length即为之后算式的长度

        bool ok=true;//判断是否仅为赋值语句
        for(i=2;i<=2+length-1;i++)
            if(whole_string[i]<'0'||whole_string[i]>'9')
                ok = false;

        if(ok)//仅为赋值语句直接赋值即可
        {
            int tem_number = 0;
            for(i=2;i<=2+length-1;i++)
                tem_number = tem_number*10 + whole_string[i] - '0';
            my_map[whole_string[0]] = tem_number;
        }
        else//将中值式变为后缀式
        {
            int top_output=0,top_sign=0;//两个栈顶指针(数组模拟栈)
            char output[1000][1000];
            char sign[1000];
            char str[1000];
            for(i=0;i<length;i++)
                str[i] = whole_string[split+1+i];//将整个运算式复制到str中
            //cout << str << endl;
            for(i=0;i<length;i++)
            {
                if(str[i]>='0'&&str[i]<='9')//是数字压入输出栈
                {
                    for(j=i+1;j<length;j++)
                        if(str[j]<'0'||str[j]>'9')
                            break;
                    for(k=0;k<j-i;k++)
                        output[top_output][k] = str[i+k];
                    output[top_output++][k] = '\0';
                    i = j-1;
                }
                else if((str[i]>='a'&&str[i]<='z')||str[i]>='A'&&str[i]<='Z')//是字母将其对应的数字压入栈
                {
                    char tem_char[1000];
                    int tem_count = 0;
                    int tem_number = my_map[str[i]];
                    //cout << "tem:" << tem_number << endl;
                    while(tem_number)//将数字转成char存入output栈
                    {
                        tem_char[tem_count++] = tem_number%10 + '0';
                        tem_number/=10;
                    }
                    for(j=0;j<tem_count;j++)
                    {
                        output[top_output][j] = tem_char[tem_count-j-1];
                    }

                    output[top_output++][j] = '\0';

                }
                else               //字符对其进行操作
                {
                    if(top_output==0)
                        sign[top_sign++] = str[i];
                    else
                    {
                        if(str[i] == ')')//当为右括号将符号弹入输出栈直至左括号
                        {

                            while(sign[top_sign-1]!='(')
                            {
                                output[top_output][0] = sign[top_sign-1];
                                output[top_output++][1] = '\0';
                                top_sign--;
                            }
                            top_sign--;
                        }
                        else
                        {
                            if(top_sign==0)
                                sign[top_sign++] = str[i];
                            else
                            {
                                //读入符号优先级大于栈顶元素优先级将其压入符号栈
                                if(compare(str[i],sign[top_sign-1])||sign[top_sign-1]=='(')
                                    sign[top_sign++] = str[i];
                                //若读入符号优先级小于栈顶元素则将栈顶元素弹出到输出栈并将符号压入符号栈
                                else
                                {
                                    output[top_output][0] = sign[top_sign-1];
                                    output[top_output++][1] = '\0';
                                    top_sign--;
                                    sign[top_sign++] = str[i];
                                }
                            }
                        }
                    }
                }
            }

            while(top_sign)//符号栈不为空
            {
                output[top_output][0] = sign[top_sign-1];
                output[top_output++][1] = '\0';
                top_sign--;
            }

            //开始对后缀表达式求值(栈)
            int top_ans=0;
            int ans[1000];

            for(i=0;i<top_output;i++)
            {
                if(output[i][0]>='0'&&output[i][0]<='9')//若为数字存入栈
                {
                    int tem = 0;
                    //从0到k-1为一个数
                    for(k=1;;k++)
                        if(output[i][k]=='\0')
                            break;
                    for(j=0;j<=k-1;j++)
                        tem = tem*10 + output[i][j] - '0';

                    ans[top_ans++] = tem;

                }//ans[top_ans++] = output[i]-'0';

                else                              //若为操作符进行操作
                {
                    ans[top_ans-2] = operation(ans[top_ans-2],ans[top_ans-1],output[i][0]);
                    top_ans--;
                }
            }
            my_map[whole_string[0]] = ans[0];
            //cout << ans[0] << endl;
        }
        cout << whole_string[0] << "=" << my_map[whole_string[0]] << endl ;
    }
    return 0;
}


  • 0
    点赞
  • 0
    评论
  • 4
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值