中缀表达式计算器

来源:互联网 发布:如何评价奥巴马 知乎 编辑:程序博客网 时间:2024/05/23 00:04
中缀表达式的计算主要要转换为后缀表达式。

例如       中缀表达式->(1+2)*3-4         转换为后缀表达式   12+3*4-

至于后缀表达式的计算就很容易了     设定一个栈,然后后缀表达式从左到右一次进栈,如果当前的入栈的是数字就将其压入栈中,

如果是运算符,就从栈中弹出两个数字进行相应的运算,然后将运算后的数字压回栈中。当字符串完全处理之后,栈顶就是运算结果

PS:输入的后缀表达式是合法的才行。

那么中缀表达式如何转换为后缀表达式?(ch接受中缀表达式传递过来的字符)

1:ch 是'(' 放入栈;

2: ch 是 ‘)’一次输入栈中的运算符,直到遇到‘(’为止

3:如果ch是其它的合法字符,将ch与当前栈顶比较

    a:ch优先级高于栈顶元素,ch入栈

    b:ch 优先级低于或者等于 栈顶元素,输出栈顶元素,ch入栈

4:如果中缀表达式读取完成,依次输出栈中的元素直到栈空

 

 

举个例子:

对于中缀表达式 (A-B)/C+D

1 : '('进栈

2:A->压入输出字符

3:- 入栈

4:B 压入输出字符串

5: ')'一次输出栈里面的字符到输出字符串

6: ‘/’ 入栈

7: C 压入字符串

8: ’+‘    ’/‘出栈 然后’+‘入栈

9: D    压入输出字符串

10: 将栈中剩下的字符串依次输出

 

// calc.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX_STACK_SIZE 100#define MAX_EXPR_SIZE 100void postfix(char *expr, char *outstr);int eval(char *outstr);typedef enum {    lparen,    rparen,    pluss,    minuss,    timess,    divide,    mod,    eos,    operand } precedence;int stack_int[MAX_STACK_SIZE];precedence stack_prece[MAX_STACK_SIZE];char expr[MAX_EXPR_SIZE];int isp[] = { 1, 19, 12, 12, 13, 13, 13, 0 };int icp[] = { 20, 19, 12, 12, 13, 13, 13, 0 };#define INT_ITEM 1#define PRECE_ITEM 2//入栈void push(int *top, int a, precedence b, int flag){    if (*top >= MAX_STACK_SIZE - 1)    {        printf("stack overflow.\n");        exit(1);    }    //不同类型的元素进入不同的栈    if (flag == INT_ITEM)        stack_int[++*top] = a;    else if (flag == PRECE_ITEM)        stack_prece[++ *top] = b;}//出栈void pop(int *top, int *a, precedence *b, int flag){    if (*top < 0)    {        printf("stack overflow.\n"); exit(1);    }    //函数传进来的 a 和 b 分别接受不同的数值    if (flag == INT_ITEM)        *a = stack_int[(*top)--];    else if (flag == PRECE_ITEM)        *b = stack_prece[(*top)--];}//将运算符号转换为特定的符号precedence get_token(char *symbol, int *n, char *expr){    *symbol = expr[(*n)++];              // n 表示的是位置    switch (*symbol)    {        case '(': return lparen;        case ')': return rparen;        case '+': return pluss;        case '-': return minuss;        case '*': return timess;        case '/': return divide;        case '%': return mod;        case '\0': return eos;        default: return operand;        //数字即被操作的符号    }}//特定的符号转换为运算符号char precedencetochar(precedence token){    switch (token)    {        case pluss: return '+';        case minuss: return '-';        case divide: return '/';        case timess: return '*';        case mod: return '%';        case eos: return '\0';      //结束符号        default: return operand;    //数字    }}//将中缀表达式转换为后缀表达式void postfix(char *expr, char *outstr){    char symbol;    precedence token, precevalue;    int n = 0;    int intvalue;    int i = 0;    int top = -1;    stack_prece[0] = eos;    for (token = get_token(&symbol, &n, expr); token != eos; token = get_token(&symbol, &n, expr))    {        //如果取得的栈顶元素是数字存到新的数组中        if (token == operand)            outstr[i++] = symbol;        //如果遇到括号        else if (token == rparen){            while (stack_prece[top] != lparen)            {                pop(&top, &intvalue, &precevalue, PRECE_ITEM);                outstr[i++] = precedencetochar(precevalue);            }            pop(&top, &intvalue, &precevalue, PRECE_ITEM);        }        //如果入栈的运算符优先级比当前栈顶的优先级低,弹出当前栈顶        else        {            if (top >= 0)            while (isp[stack_prece[top]] >= icp[token])            {                pop(&top, &intvalue, &precevalue, PRECE_ITEM);                outstr[i++] = precedencetochar(precevalue);            }            push(&top, 0, token, PRECE_ITEM);        }    }    while (top >= 0)    {        pop(&top, &intvalue, &precevalue, PRECE_ITEM);        outstr[i++] = precedencetochar(precevalue);    }    outstr[i] = '\0';}//计算后缀表达式int eval(char *outstr){    precedence token, precevalue;    char symbol;    int op1, op2, result;    int n = 0;    int top = -1;    token = get_token(&symbol, &n, outstr);    precevalue = token;    while (token != eos)    {        if (token == operand)        {            push(&top, symbol - '0', precevalue, INT_ITEM);        }        else        {            pop(&top, &op2, &precevalue, INT_ITEM);            pop(&top, &op1, &precevalue, INT_ITEM);            switch (token)            {                case pluss: push(&top, op1 + op2, precevalue, INT_ITEM); break;                case minuss: push(&top, op1 - op2, precevalue, INT_ITEM); break;                case timess: push(&top, op1*op2, precevalue, INT_ITEM); break;                case divide: push(&top, op1 / op2, precevalue, INT_ITEM); break;                case mod: push(&top, op1%op2, precevalue, INT_ITEM); break;                default: break;            }        }        token = get_token(&symbol, &n, outstr);    }    pop(&top, &result, &precevalue, INT_ITEM);    return result;}int _tmain(int argc, _TCHAR* argv[]){    char expr[100], outstr[100];    int result;    gets(expr);                          //输入的字符串    postfix(expr, outstr);    result = eval(outstr);    printf("the result is %d\n", result);    return 0;}

 

0 0