后缀表达式计算

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define MAXSIZE 30

typedef struct
{
    char data[MAXSIZE];
    int top;
} SqStack;
typedef struct
{
    double data[MAXSIZE];
    int top;
} SqStack1;
//栈的初始化 
void Stack_Init(SqStack *s)
{
    s->top = 0;
}

void Stack_Init1(SqStack1 *s)
{
    s->top = 0;
}
//判断栈是否为空
int Stack_Empty(SqStack *s)
{
    if (s->top>0)
        return 1;
    else
        return 0;
}
//入栈
void Stack_Push(SqStack *s, char ch)
{
    if (s->top == MAXSIZE)
    {
        printf("栈满。无法入栈!!!\n");
    }
    else
    {
        s->data[s->top++] = ch;
        //printf("  %c入栈! \n ", ch);
    }
}

void Stack_Push1(SqStack1 *s, double n)
{
    if (s->top == MAXSIZE)
    {
        printf("栈满。无法入栈!!!\n");
    }
    else
    {
        s->data[s->top++] = n;
        //printf("  %f入栈! \n ", n);
    }
}
void Stack_Pop(SqStack *s)
{
    if (s->top == 0)
        printf("栈空,无法出栈!!!!!!\n");
    else
    {
        //printf("  %c出栈! \n ", s->data[s->top-1]);
        s->top--;
    }
}
void Stack_Pop1(SqStack1 *s)
{
    if (s->top == 0)
        printf("栈空,无法出栈!!!!!!\n");
    else
    {
        //printf("  %f出栈! \n ", s->data[s->top - 1]);
        s->top--;
    }
}
//判断字符是否是操作符
int Isoperationa(char ch)
{
    int flag = 0;
    if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
        flag = 1;
    else
        flag = 0;
    return flag;
}
//判断符号优先级
int priority(char ch)
{
    int flag = 0;
    switch (ch)
    {
    case'(':
        flag = 0;
        break;
    case ')':
        flag = 0;
        break;
    case '#':
        flag = -1;
        break;
    case '+':
        flag = 1;
        break;
    case '-':
        flag = 1;
        break;
    case '*':
        flag = 2;
        break;
    case'/':
        flag = 2;
        break;
    default:
        break;
    }
    return flag;
}
//验证表达式是否匹配
void marry(char *infix)
{
    int i = 0;
    SqStack sta;
    SqStack *s = &sta;
    Stack_Init(s);
    if (Isoperationa(infix[0]))
    {
        printf("非法输入!!!\n");
        system("pause");
        exit(-1);
    }
    while (infix[i] != '\0')
    {
        if (Isoperationa(infix[i]) && Isoperationa(infix[i + 1]))
        {
            printf("非法输入!!!\n");
            system("pause");
            exit(-1);
        }
        i++;
    }
    i = 0;
    while (infix[i] != '\0')
    {
        if (infix[i] != '+' && infix[i] != '-' && infix[i] != '*' && infix[i] != '/'&&infix[i] != '('&&infix[i] != ')' && (infix[i] < '0' || infix[i] > '9')&&infix[i]!='.')
        {
            printf("非法输入!!!\n");
            system("pause");
            exit(-1);
        }
        i++;
    }
    i = 0;
    while (infix[i] != '\0')
    {
        if (infix[i] == '(')
            Stack_Push(s, infix[i]);
        if (infix[i] == ')')
        {
            if (s->top == 0)
            {
                printf("括号不匹配!!!\n");
                system("pause");
                exit(-1);
            }
            else
                Stack_Pop(s);
        }
        i++;
    }
    if (s->top != 0)
    {
        printf("括号不匹配!!!\n");
        system("pause");
        exit(-1);
    }
    if (Isoperationa(infix[i-1]))
    {
        printf("非法输入!!!\n");
        system("pause");
        exit(-1);
    }
}
/*-------------------------------------
  中缀表达式转后缀表达式
  遍历中缀表达式中所有字符
  1.若是数字直接输出成为后缀表达式的一部分;

  2.若是符号则判断其与栈顶符号优先级是右括号
  优先级不高于栈顶符号将栈顶元素依次出栈输出成为后缀表达式一部分
  将当前符号入栈直到遍历完中缀表达式且栈空为止

  3.输出后缀表达式
  -------------------------------------*/
void InfixToSuffix(char *infix, char *suffix)
{
    SqStack sufstack;
    SqStack *p = &sufstack;
    Stack_Init(p);
    int i = 0, j = 0;

    while (infix[i]!='\0')
    {
        if (infix[i] >= '0'&&infix[i] <= '9'||infix[i]=='.')
        {
            suffix[j] = infix[i];
            i++;
            j++;
        }

        else if (Isoperationa(infix[i]))
        {
            suffix[j++] = ' ';
            while (priority(infix[i]) <= priority(p->data[p->top - 1]))
            {
                suffix[j++] = p->data[p->top-1];
                Stack_Pop(p);
            }
            Stack_Push(p, infix[i]);
            i++; 
        }
        else if (infix[i] == '(')
        {
            Stack_Push(p, infix[i]);
            i++;
        }
        else if (infix[i] == ')')
        {
            while (p->data[p->top - 1] != '(')
            {
                suffix[j++] = p->data[p->top - 1];
                Stack_Pop(p);
            }
            if (p->data[p->top - 1] = '(')
            {
                Stack_Pop(p);
            }
            i++;
        }
        else if (infix[i] == '.')
            i++;
    }
    while (Stack_Empty(p))
    {
        suffix[j++] = p->data[p->top-1];
        Stack_Pop(p);
    }
    suffix[j] = '\0';
}
//将后缀表达式中字符转换为数字
double SuffixtoInt(char *suffix,int *i)
{
    double num = 0.0;
    int j = 0;
    while (suffix[*i]<'0' || suffix[*i]>'9')
        (*i)++;
    while (suffix[*i] >= '0' && suffix[*i] <= '9')
    {
        num = num * 10 + suffix[*i] - '0';
        (*i)++;
    }
    if (suffix[*i] == '.')
    {
        (*i)++;
        while (suffix[*i] >= '0' && suffix[*i] <= '9')
        {
            j++;
            num = num * 10 + suffix[*i] - '0';
            (*i)++;
        }
    }
    for (; j > 0; j--)
    {
        num = num / 10;
    }
    return num;
}
/*--------------------------------------------
      后缀表达式计算结果

      遍历后缀表达式遇到数字就进栈遇到符号就
      将栈顶两个数字出栈进行运算并将计算结果
      入栈直到获得结果

  --------------------------------------------*/
double Suffix_answer(char *suffix)
{
    int i = 0;
    double answer = 0.0;
    SqStack1 Sta;
    SqStack1 *p = &Sta;
    Stack_Init1(p);
    while (suffix[i] != '\0')
    {
        if (suffix[i] >= '0' && suffix[i] <= '9'||suffix[i]=='.')
            Stack_Push1(p, SuffixtoInt(suffix, &i));

        else if (Isoperationa(suffix[i]))
        {
            switch (suffix[i])
            {
                case '+': 
                    answer = p->data[p->top - 2] + p->data[p->top - 1]; 
                    Stack_Pop1(p);
                    Stack_Pop1(p);
                    Stack_Push1(p, answer);
                    i++;
                    break;
                case '-':
                    answer = p->data[p->top - 2] - p->data[p->top - 1];
                    Stack_Pop1(p);
                    Stack_Pop1(p);
                    Stack_Push1(p, answer);
                    i++;
                    break;
                case '*':
                    answer = p->data[p->top - 2] * p->data[p->top - 1];
                    Stack_Pop1(p);
                    Stack_Pop1(p);
                    Stack_Push1(p, answer);
                    i++;
                    break;
                case '/':
                    answer = p->data[p->top - 2] / p->data[p->top - 1];
                    Stack_Pop1(p);
                    Stack_Pop1(p);
                    Stack_Push1(p, answer);
                    i++;
                    break;
            }
        }
        else
            i++;
    }  
    return answer;
}
int main(int argc, char *argv[])
{
    system("color 0A");
    int i = 0;
    int flag;
    char ch;
    char infix[30] = "";
    char suffix[30]="";
    printf("\t\t*****************************************************\n");
    printf("\t\t*                           *\n");
    printf("\t\t*                           *\n");
    printf("\t\t*       计       算       器           *\n");
    printf("\t\t*                           *\n");
    printf("\t\t*                           *\n");
    printf("\t\t*****************************************************\n\n");
    while (1)
    {
        i = 0;
        printf("\t\t请输入表达式:");
        while ((ch = getchar()) != '\n')
        {
            infix[i++] = ch;
        }
        infix[i] = '\0';
        marry(infix);
        printf("\t\t中缀表达式:%s\n", infix);
        InfixToSuffix(infix, suffix);
        printf("\t\t后缀表达式:%s\n", suffix);
        printf("\t\t计算结果:%f\n\n\n", Suffix_answer(suffix));
        printf("\t\t是否继续 按n退出 按y继续!!\n\n\t\t");
        fflush(stdin);
        if ((flag = getchar())=='n')
            exit(0);
        if ((flag = getchar()) == 'y')
        {
            memset(infix, 0, sizeof(infix));
            memset(suffix, 0, sizeof(suffix));
        }
    }
    system("pause");
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值