表达式计算

#include <iostream>
#include <map>
#define Max_size 100
using namespace std;

typedef struct
{
    char elem[Max_size];
    int length;
}char_stack;

typedef struct
{
    int elem[Max_size];
    int length;
}int_stack;

int index (char c)
{
    if (c=='+') return 0;
    else if (c=='-') return 1;
    else if (c=='*')  return 2;
    else if (c=='/')  return 3;
    else if (c=='(')  return 4;
    else if (c==')')  return 5;
    else
        return 6;
}

int value[7][7]={{1,1,-1,-1,-1,1,1},
             {1,1,-1,-1,-1,1,1},
             {1,1,1,1,-1,1,1},
             {1,1,1,1,-1,1,1},
             {-1,-1,-1,-1,-1,0,0},
             {1,1,1,1,0,1,1},
             {-1,-1,-1,-1,-1,0,0}};

void init_optr(char_stack &s)
{
    s.length=0;
}

void init_opnd(int_stack &s)
{
    s.length=0;
}

void push_optr(char_stack &s,char c)
{
    s.elem[s.length++]=c;
}

void push_opnd(int_stack &s,int n)
{
    s.elem[s.length++]=n;
}

char pop_optr(char_stack &s)
{
    return s.elem[--s.length];
}

int pop_opnd(int_stack &s)
{
    return s.elem[--s.length];
}

char get_optr(char_stack s)
{
    return s.elem[s.length-1];
}

int cal(int a,int b,char c)
{
    int sum;
    switch (c){
        case '+':sum=a+b;break;
        case '-':sum=a-b;break;
        case '*':sum=a*b;break;
        case '/':sum=a/b;break;
    }
    return sum;
}

int infix_cal(string s)
{
    char_stack optr;
    int_stack opnd;
    init_optr(optr);
    init_opnd(opnd);
    push_optr(optr, '#');
    char topoptr, c;
    int num = 0, a, b, i = 0;
    topoptr = get_optr(optr);
    while(s[i] != '#' || topoptr != '#')
    {
        if (s[i] >= '0' && s[i] <= '9')
        {
            num = 0;
            while (s[i] >= '0' && s[i] <='9')
            {
                num = num * 10 + s[i] -'0';
                i++;
            }
            push_opnd(opnd, num);
        }
        else
        {
            if (value[index(get_optr(optr))][index(s[i])] == 1)
            {//栈顶元素优先级大于当前待入栈的元素,所以要将数字栈中的元素弹出进行运算
                c = pop_optr(optr);
                b = pop_opnd(opnd);
                a = pop_opnd(opnd);
                push_opnd(opnd, cal(a, b, c));
            }
            else if(value[index(get_optr(optr))][index(s[i])] == 0)
            {//栈顶元素优先级和当前待入栈元素的优先级相等,即'('与‘)’
                c = pop_optr(optr);
                i++;
            }
            else//栈顶元素优先级小于待入栈元素,则继续入栈
                push_optr(optr, s[i++]);
        }
        topoptr = get_optr(optr);
    }
    return pop_opnd(opnd);
}

int prefix_cal(string s)
{//前缀表达式的计算
    //将表达式从后往前扫描,遇到数字就压栈,遇到运算符就将数字出栈参与运算
    //eg 1 + 2 * 3 + 4 * 5 -------> + + 1 * 2 3 * 4 5 可以看出,符号越在后面出现,符号参与运算的级别越高
    int_stack opnd;
    init_opnd(opnd);
    int length = s.length()-1, a, b, num;
    while(length >= 0)
    {
        if (s[length] >='0' && s[length] <= '9')
        {
            int k = 1;
            num = 0;
            while(s[length] >= '0' && s[length] <= '9')
            {
                num = num + k * (s[length--] - '0');
                k = k * 10;
            }
            push_opnd(opnd, num);
        }
        else
        {
            a=pop_opnd(opnd);
            b=pop_opnd(opnd);
            push_opnd(opnd, cal(a, b ,s[length--]));
        }
        length--;
    }
    return pop_opnd(opnd);
}

int suffix_cal(string s)
{//后缀表达式的计算
    //从前往后扫描,遇到数字就压栈,遇到运算符就将数字出栈参与运算
    //eg 1 + 2 * 3 + 4 * 5 -------> 1 2 3 * + 4 5 * + 可以看出运算符越在前面出现,就越应该在前面参与运算
    int_stack q;
    init_opnd(q);
    int i = 0, a, b, num = 0;
    while(i<s.length())
    {
        if(s[i]>='0'&&s[i]<='9')
        {
            num = 0;
            while(s[i] >= '0' && s[i] <= '9')
            {
                num = 10 * num + s[i++] - '0';
            }
            push_opnd(q,num);
        }
        else
        {
            b=pop_opnd(q);
            a=pop_opnd(q);
            push_opnd(q,cal(a,b,s[i++]));
        }
        i += 1;
    }
    return pop_opnd(q);
}

string infix_suffix(string s)
{//中缀转后缀
    //遇到数字就输出,遇到运算符,
    //若当前运算符优先级小于栈顶元素,则将栈顶元素弹出并输出
    //若当前运算符优先级大于栈顶元素,则将当前运算符压入栈
    //若当前运算符优先级等于栈顶元素,则将栈顶元素弹出即可
    string suffix = "";
    char_stack optr;
    init_optr(optr);
    push_optr(optr,'#');
    for(int i=0,j=0;i<s.length();)
    {
        if(s[i]>='0'&&s[i]<='9')
        {
            while(s[i] >= '0' && s[i] <= '9')
            {
                suffix = suffix + s[i++];
            }
            suffix = suffix + ' ';
        }
        else
        {
            while (value[index(get_optr(optr))][index(s[i])]==1)
            {
                suffix = suffix + pop_optr(optr);
                suffix = suffix + ' ';
            }
            if(value[index(get_optr(optr))][index(s[i])]==0)
            {
                pop_optr(optr);
                i++;
            }
            else
                push_optr(optr,s[i++]);
        }
    }
    while (get_optr(optr) != '#')
    {
        suffix = suffix + pop_optr(optr) +' ';
    }
    return suffix;
}

string infix_prefix(string s)
{
    //中缀转前缀
    //
    string prefix = "";
    char_stack p,q;
    init_optr(p);
    init_optr(q);
    push_optr(p,'#');
    push_optr(q,'#');
    for (int i=s.length()-1;i>=0;)
    {
        char c = s[i];
        if(s[i]>='0'&&s[i]<='9')
        {
            while(s[i] >= '0' && s[i] <= '9')
            {
                c = s[i];
                    push_optr(q, s[i--]);
            }
            push_optr(q,' ');
        }
        else
        {
            while(value[index(s[i])][index(get_optr(p))]==-1)
            {//当前元素小于栈顶元素的优先级,则将栈顶元素弹出,并压入数字栈
                push_optr(q,pop_optr(p));
                push_optr(q,' ');
            }
            if (value[index(s[i])][index(get_optr(p))]==0)
            {//当前元素等于栈顶元素的优先级,则将栈顶元素弹出
                pop_optr(p);
                i--;
            }
            else//当前元素大于栈顶元素的优先级,则将当前元素压入栈
                push_optr(p,s[i--]);
        }
    }
    while(get_optr(p) != '#')
    {//将剩余的符号压入数字栈中
        push_optr(q,pop_optr(p));
        push_optr(q,' ');
    }
    while(get_optr(q) != '#')
    {//最后将数字栈中的元素全部输出即为结果
        prefix = prefix + pop_optr(q);
    }
    return prefix;
}
int main()
{
    string infix,prefix,suffix;
    cin>>infix;
    cout<<infix_cal(infix)<<endl;
    cin>>infix;
    prefix = infix_prefix(infix);
    cout<<"prefix:"<<prefix<<endl;
    cout<<prefix_cal(prefix)<<endl;
    suffix = infix_suffix(infix);
    cout<<"suffix:"<<suffix<<endl;
    cout<<suffix_cal(suffix)<<endl;
    return 0;
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
用两种方式实现表达式自动计算的应用 (1)中缀表达式转后缀表达式计算(扫两遍) 创建一个数组存储输入的计算表达式。另创建一个数组储存将要生成的后缀表达式。创建一个储存操作符。 对已存储的表达式数组扫描。 判断当前节点,如果是操作数或’.’,直接加入后缀表达式中,如果是操作符,则比较前一个操作符与当前操作符的优先级。如果前一个操作符的优先级较高,则将前一个操作符加入后缀表达式中,否则将操作符压入操作符。 如果遇到左括号’(’,直接入;如果遇到右括号’)’,则在操作符中反向搜索,直到遇到匹配的左括号为止,将中间的操作符依次加到后缀表达式中。 当执行完以上操作,发现中仍有剩余操作符,则将操作符依次加到后缀表达式中。此时中缀表达式已经转换成了后缀表达式。 对后缀表达式进行计算。 如果后缀表达式为大于0小于9的字符,则将它转换成浮点型数据并存入数中。如果遇到操作符,则从数中提取两个数,进行相应的运算。依次进行下去,当没有运算符是,运算结束得到最后的结果。 (2)表达式求值(扫一遍) 创建一个数组存储输入的计算表达式。创建两个,一个字符型的,一个双精度型的。分别用来存储字符和数。 对已存储的表达式数组扫描。 判断当前节点,如果是操作数和’.’,将字符型的操作数转换为浮点型的数后存入操作数。 如果是操作符则判断操作符的优先级。如果字符中已存储符号的优先级小于要存入的字符的优先级,则直接让字符入操作符。如果字符中已存储符号的优先级大于或等于要存入的字符的优先级,则取出操作符中的一个字符和操作数中的两个数进行计算,然后将结果存入操作数中,同上进行下去,直到字符中已存储符号的优先级小于要存入的字符的优先级时,将操作符存入操作符中。 当遇到左括号’(’,将左括号直接存入操作符中。当遇到右括号’)’,则在操作符中反向搜索,并且每搜到一个字符就在操作数中取两个数进行相应的计算。然后,将运算结果存入到操作符中。如此进行下去,直到遇到左括号结束。将左括号从中取出。最后,如果操作符中还有符号,就从操作符顶开始将操作符取出并从操作数顶开始取出两个数字进行计算,将结果存入操作数中。重复上述操作直到操作符中没有操作符,得到运算结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值