栈之计算表达式值

算法思想:

  1. 规定运算符的优先级表
  2. 设置两个栈,运算数栈,运算符栈。
  3. 输入一个表达式,自左向右扫描,进行如下处理:若遇到运算数则进栈,若遇到运算符,则与运算符栈中的栈顶元素进行优先级比较。1.如果当前运算符优先级大于栈顶元素的优先级,则当前运算符进栈。2.如果当前运算符的优先级小于等于栈顶元素的优先级,则运算符栈退栈一次,运算数栈退栈两次,得到运算数a和运算数b和运算符op,执行运算后将得到的结果压进运算数栈。

    先是两个头文件:
    NumLinkStack.h

#include<stdio.h>
#include<stdlib.h>

typedef struct  Node1
{
    int data;
    struct  Node1 *next;
}NumNode, *NumStack;

int NumInitStack(NumStack *L)
{
    (*L) = (NumNode *)malloc(sizeof(NumNode));
    if (!(*L))
    {
        return 0;
    }
    else
    {
        (*L)->next = NULL;
        return 1;
    }
}

int NumPush(NumStack L,int x)
{
    NumNode *temp;
    temp = (NumNode *)malloc(sizeof(NumNode));
    if (!temp)
    {
        return 0;
    }

    temp->data = x;
    temp->next = L->next;
    L->next = temp;
    return 1;
}

int NumPop(NumStack L, int *x)
{
    NumNode *temp;
    temp = L->next;

    if (temp==NULL)
    {
        return 0;
    }
    *x = temp->data;
    L->next = temp->next;
    free(temp);
    return 1;
}

int NumGetTop(NumStack L)
{
    if (L->next==NULL)
    {
        return 0;
    }
    else
    {
        return L->next->data;   
    }
}

OperaLinkStack.h

#include<stdio.h>
#include<stdlib.h>

typedef struct  Node2
{
    char data;
    struct  Node2 *next;
}OperaNode, *OperaStack;

int OperaInitStack(OperaStack *L)
{
    (*L) = (OperaNode *)malloc(sizeof(OperaNode));
    if (!(*L))
    {
        return 0;
    }
    else
    {
        (*L)->next = NULL;
        return 1;
    }
}

int OperaPush(OperaStack L, char x)
{
    OperaNode *temp;
    temp = (OperaNode *)malloc(sizeof(OperaNode));
    if (!temp)
    {
        return 0;
    }

    temp->data = x;
    temp->next = L->next;
    L->next = temp;
    return 1;
}

int OperaPop(OperaStack L, char *x)
{
    OperaNode *temp;
    temp = L->next;

    if (temp == NULL)
    {
        return 0;
    }
    *x = temp->data;
    L->next = temp->next;
    free(temp);
    return 1;
}

char OperaGetTop(OperaStack L)
{
    if (L->next==NULL)
    {
        return 0;
    }
    else
    {
        return L->next->data;    
    }
}

主函数:

#include "NumLinkStack.h"
#include "OperaLinkStack.h"
#include <math.h>
#include <string.h>

int ExpEvaluation(NumStack N, OperaStack L);//计算函数

int Judege(char ch);//判断是否为运算符

char Compare(char ch, char ch2);//判断运算符的优先级

int Execute(int a, char op, int b);//运算

int main(void)
{
    NumStack N;
    OperaStack L;
    NumInitStack(&N);
    OperaInitStack(&L);

    printf("%d",ExpEvaluation(N, L));
    getchar();
    getchar();

    return 0;
}

int ExpEvaluation(NumStack N, OperaStack L)
{
    char express[100];
    int i = 0;
    int k = 0;
    int j = 0;
    int num2 = 0;
    char e;
    int a, b;
    char op;
    OperaPush(L, '=');

    printf("Please input an expresion (Ending with =)\n");
    scanf("%s",express);

    while (express[i] != '='|| OperaGetTop(L) != '=')
    {
        if (express[i] >= '0'&&express[i] <= '9')
        {
            k++;
            if (k<=j)//判断此时为几位数,如果j大于k时,表明前面的为运算符,num2从个位开始相加,故num2不用归零了
            {
                num2 = express[i] - 48;
                i++;
            }
            if (k>j)
            {
                num2 = num2 * 10 + (express[i] - 48);
                k = j = 0;
                i++;
            }
            if (!Judege(express[i]))//如果后面的数还是运算数的话,k++
            {
                k++;
            }
            if (k==j)//表明后面的为运算符了,将前面的数字压栈
            {
                NumPush(N, num2);
            }
        }
        else if (Judege(express[i]))
        {
            switch (Compare(express[i], OperaGetTop(L)))
            {
            case '<':
                OperaPush(L, express[i++]);
                if (express[i] != '('&&express[i] != ')')//当运算符为括号时,不进行j++操作例23+(56*5)
                     j++;
                break;

            case '=':
                OperaPop(L, &e);//脱括号,并接受下一个字符
                i++;
                break;

            case '>':
                OperaPop(L, &op);
                NumPop(N, &b);
                NumPop(N, &a);
                NumPush(N, Execute(a, op, b));//注意此处运算结束后,i不加一
                break;
            }
        }
    }        
     return NumGetTop(N);
}

int Judege(char ch)
{
    char ptr[8] = { '+', '-', '*', '/', '(', ')', '=' };
    int i;
    for (i = 0; i < 7; i++)
    {
        if (ch == ptr[i])
            return 1;
    }
    return 0;
}

char Compare(char a, char b)
{
    int i, j;
    char Table[8][8] =
    {
        { ' ', '+', '-', '*', '/', '(', ')', '=' },
        { '+', '>', '>', '<', '<', '<', '>', '>' },
        { '-', '>', '>', '<', '<', '<', '>', '>' },
        { '*', '>', '>', '>', '>', '<', '>', '>' },
        { '/', '>', '>', '>', '>', '<', '>', '>' },
        { '(', '<', '<', '<', '<', '<', '=', ' ' },
        { ')', '>', '>', '>', '>', ' ', '>', '>' },
        { '=', '<', '<', '<', '<', '<', ' ', '=' }
    };  //优先级表格
    for (i = 0; i < 8; i++)
    if (Table[0][i] == a)  //纵坐标寻找
        break;
    for (j = 0; j < 8; j++)  //横坐标寻找
    if (Table[j][0] == b)
        break;
    return Table[j][i];
}

int Execute(int a, char op, int b)
{
    switch (op)
    {
    case '+':return a + b;
    case '-':return a - b;
    case '*':return a * b;
    case '/':return a / b;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值