栈之计算表达式值

来源:互联网 发布:蚁群算法matlab 编辑:程序博客网 时间:2024/05/18 20:05

算法思想:

  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
原创粉丝点击