c语言数据结构课程与设计---用栈求基本表达式的值

利用栈求表达式的值

(1)问题描述

用c或c++语言编写程序实现表达式求值,即验证某算术表达式的正确性,若正确,则计算该算术表达式的值。表达式从键盘输入后,按以下方法对该表达式中成份逐个进行分析:

(1)若是数字,则判断该数字的合法性。若合法,则压入数据到堆栈中。

(2)若是规定的运算符,则根据规则进行处理。在处理过程中,将计算该表达式的值。

(3)若是其它字符,则返回错误信息。

若上述处理过程中没有发现错误,则认为该表达式合法,并打印处理结果。

(2)要求

用栈数据结构实现,且程序中应主要编写如下几个功能函数:

 void initstack():初始化栈。

 int Make_str():语法检查并计算。

 int push_operate(int operate):将操作码压入堆栈。

 int push_num(double num):将操作数压入堆栈。

 int procede(int operate):处理操作码。

 int change_opnd(int operate):将字符型操作码转换成优先级。

 int push_opnd(int operate):将操作码压入堆栈。

 int pop_opnd():将操作码弹出堆栈。

 int caculate(int cur_opnd):简单计算+,-,*,/,(,)。

 double pop_num():弹出操作数。

  1. 主要任务和目标

用c语言编写程序实现表达式求值,输入形式为0到9数字和基础运算符,输出的形式为数字,程序能实现的功能为整数与整数的加减乘除和带括号运算。

测试数据:

(1)结尾必须输入‘#’字符,若没有输入,则重新输入。

(2)若是数字,则判断该数字的合法性。若合法,则压入数据到堆栈中。

(3)若是规定的运算符,则根据规则进行处理。在处理过程中,将计算该表达式的值。

(4)若是其它字符,则返回错误信息,并重新输入。

(5)若数字与运算符皆合法,则判断运算表达式是否合法,若不合法则重新输入。

代码:

#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#define SIZE 50
typedef  int Elemtype;

//数字栈结构体
typedef struct {
    Elemtype elem[SIZE];
    int top;
    int base;
} SeqStack;

//运算符结构体
typedef struct {
    char a[SIZE];
    char top;
    char base;
} SqStack;

//初始化
void Init1(SeqStack *S1) {
    S1->top = -1;
}

void Init2(SqStack *S2) {
    S2->top = -1;
}

//入栈
int Push1(SeqStack *S1, Elemtype x) {
    if (S1->top == SIZE - 1)
        return false;
    S1->top++;
    S1->elem[S1->top] = x;
    return true;
}

int Push2(SqStack *S2, char x) {
    if (S2->top == SIZE - 1)
        return false;
    S2->top++;
    S2->a[S2->top] = x;
    return true;
}

//出栈
int Pop1(SeqStack *S1, Elemtype *x) {
    if (S1->top == -1)
        return false;
    else {
        *x = S1->elem[S1->top];
        S1->top--;
        return true;
    }
}

int Pop2(SqStack *S2, char *x) {
    if (S2->top == SIZE - 1)
        return false;
    else {
        *x = S2->a[S2->top];
        S2->top--;
        return true;
    }
}

//读栈顶元素
int GetTop1(SeqStack *S1 ) {
    Elemtype x;
    if (S1->top == -1)
        return false;
    else {
        x = S1->elem[S1->top];
        return x;
    }
}

int GetTop2(SqStack *S2) {
    char x;
    if (S2->top == -1)
        return false;
    else {
        x = S2->a[S2->top];
        return x;
    }
}

//判断字符是否合法
int IsStr(char c) {
    int a;
    switch (c) {//是运算符返回1  其他返回-1
        case'+':
        case'-':
        case'*':
        case'/':
        case'(':
        case')':
        case'#':
            a = 1;
            break;
        case'0':
            case'1':
                case'2':
                    case'3':
                        case'4':
                            case'5':
                                case'6':
                                    case'7':
                                        case'8':
                                            case'9':
                                                    a = 0;
            break;
        default: {
            a = -1;
            break;
        }

    }
    return a;
}

char Precede(char a, char b) {
    //比较运算符的优先级
    char f;
    if (a == '+' || a == '-') {
        if (b == '+' || b == '-' || b == ')' || b == '#')
            f = '>';
        else if (b == '*' || b == '/' || b == '(')
            f = '<';
    } else if (a == '*' || a == '/') {
        if (b == '+' || b == '-' || b == '*' || b == '/' || b == ')' || b == '#')
            f = '>';
        else if (b == '(')
            f = '<';
    } else if (a == '(') {
        if (b == '+' || b == '-' || b == '*' || b == '/' || b == '(')
            f = '<';
        else if (b == ')')
            f = '=';
    } else if (a == ')') {
        if (b == '+' || b == '-' || b == '*' || b == '/' || b == ')' || b == '#')
            f = '>';
    } else if (a == '#') {
        if (b == '+' || b == '-' || b == '*' || b == '/' || b == '(')
            f = '<';
        else if (b == '#')
            f = '=';
    } else
        f = '!';
    return f;
}

int Operate(int i, char theta, int j) {
    //计算a(theta)b结果
    int result;
    switch (theta)   {
        case '+':
            result = i + j;
            break;
        case '-':
            result = i - j;
            break;
        case '*':
            result = i * j;
            break;
        case '/':
            result = i / j;
            break;
    }
    return result;
}

//计算表达式
int Parse() {
    SeqStack S1;
    SqStack S2;
    Init1(&S1);
    Init2(&S2);
    int IsStr(char c);
    char ch[SIZE];
    int a, b, c, tot;
    char x, oper;
    int t = 0;//遍历字符数组

flag:
    int i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, len = 0;

    printf("提示:输入表达式请在英文状态下输入,字符之间不能出现空格,结尾请输入‘#’字符\n");
    printf("输入:");
    scanf("%s", ch);
    while (ch[i] != '\0') {
        len++;
        i++;
    }
    if (ch[len - 1] != '#') {
        printf("结尾未输入‘#’,请重新输入\n");
        free(ch);
        goto flag;
    }
    while (ch[m] != '\0') {
        if (IsStr(ch[m]) == -1) {
            printf("输入错误字符!\n");
            goto flag;
        }
        m++;
    }
    while (ch[k] != '\0') {
        if (ch[k] == '/' && ch[k + 1] == '0') {
            printf("除数不能为零!\n");
            goto flag;
        }
        k++;
    }
    while (ch[n] != '\0') {
        if (ch[n] == '/' || ch[n] == '*' && ch[n + 1] == ')') {
            printf("运算表达式错误!\n");
            goto flag;
        } else if (ch[n] == '(' && ch[n + 1] == '*' || ch[n + 1] == '/') {
            printf("运算表达式错误!\n");
            goto flag;
        }
        n++;
    }
    Push2(&S2, '#');
    while (ch[t - 1] != '#' ) {
        printf(" %c\n", ch[t]);
        if (IsStr(ch[t]) == 0) {
            tot = ch[t] - 48;
            Push1(&S1, tot);
        } else  if (IsStr(ch[t]) == 1) {
            switch (Precede(GetTop2(&S2), ch[t])) {
                case'>': {
                    Pop2(&S2, &oper);
                    Pop1(&S1, &b);
                    Pop1(&S1, &a);
                    Push1(&S1, Operate(a, oper, b) );
                    break;
                }
                case'<': {
                    Push2(&S2, ch[t]);
                    break;
                }
                case'=': {
                    Pop2( &S2, &x);
                    break;
                }
            }
        }
        t++;
    }

    printf("结果为:%d\n", GetTop1(&S1));
    return 0; 
}

int main() {
    Parse();
    return 0;
}

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值