C语言表达式求解

主要思路:
1. 将从键盘输入的中缀表达式转换成后缀表达式存放在一个结点p的字符串成员变量中;
2. 利用后缀表达式进行表达式的计算,并将结果存入结点p的res成员变量中,最后将该结点以尾插的方式插入链表中;
3. 遍历整个链表就得到所有表达式的结果了。
关键:
中缀到后缀表达式的转换以及后缀表达式的计算的关键在于对符号栈和操作数栈的使用。

/*-------------------------------------------------------------------------------------
功能:实现表达式的计算,其中可包括+ - * / () 浮点数
输入示例:
3
1+2+3+4+5+10
2.2/3+100
(56-40)/(4+2)
输出示例:
res = 25.0
res = 100.7
res = 2.7
Author: Zhang Kaizhou
Date: 2019-3-5 16:58:59
------------------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 1000

typedef struct node{ // 定义一个Node数据类型,用于存放后缀表达式以及最终结果
    char post_str[MAXSIZE];
    double res;
    struct node * pnext;
} Node;

typedef struct{ // 定义一个字符栈数据类型
    char oper[MAXSIZE];
    int top_oper;
} SqStack;

typedef struct{ // 数据栈数据类型
    double data[MAXSIZE];
    int top_data;
} DataStack;

void in_to_post(char * in_str, Node * p);
void compute_value(Node * p);
void push_oper(SqStack * p_oper, char ch);
void pop_oper(SqStack * p_oper, char * ch);
void get_top_oper(SqStack * p_oper, char * ch);
void push_data(DataStack * p_data, double num);
void pop_data(DataStack * p_data, double * num);
void get_top_data(DataStack * p_data, double * num);
void list_tail_insert(Node ** pphead, Node ** pptail, Node * p);
void list_print(Node * phead);

int main(){
    char in_str[MAXSIZE];
    Node * phead = NULL, * ptail = NULL;
    int n, i;

    scanf("%d", &n);
    for(i = 0; i < n; i++){
        while(scanf("%s", in_str), getchar() != '\n'); // 每次从键盘读取一行字符串,以回车结束
        Node * pnew = (Node *)calloc(1, sizeof(Node));
        in_to_post(in_str, pnew);
        compute_value(pnew);
        list_tail_insert(&phead, &ptail, pnew);
    }
    list_print(phead);

    free(phead);
    free(ptail);
    return 0;
}

void in_to_post(char * in_str, Node * p){ // 将中缀表达式转换成后缀表达式
    SqStack * p_oper = (SqStack *)calloc(1, sizeof(SqStack)); // 定义一个栈指针,并初始化
    p_oper->top_oper = -1;
    int i = 0;
    char temp;
    while(* in_str != '\0'){
        switch(* in_str){
        case '(':
            push_oper(p_oper, '('); in_str++; break;
        case ')':
            pop_oper(p_oper, &temp);
            while(temp != '('){
                p->post_str[i++] = temp;
                pop_oper(p_oper, &temp);
            }
            in_str++; break;
        case '+':
        case '-':
            while(p_oper->top_oper >= 0){
                get_top_oper(p_oper, &temp);
                if(temp != '('){
                    p->post_str[i++] = temp;
                    pop_oper(p_oper, &temp);
                }else{
                    break;
                }
            }
            push_oper(p_oper, * in_str);
            in_str++; break;
        case '*':
        case '/':
            while(p_oper->top_oper >= 0){
                get_top_oper(p_oper, &temp);
                if(temp == '*' || temp == '/'){
                    p->post_str[i++] = temp;
                    pop_oper(p_oper, &temp);
                }else{
                    break;
                }
            }
            push_oper(p_oper, * in_str);
            in_str++; break;
        default:
            while((* in_str >= '0' && * in_str <= '9') || * in_str == '.'){
                p->post_str[i++] = * in_str;
                in_str++;
            }
            p->post_str[i++] = '#'; // 用#表示一个数字串结束
        }
    }
    while(p_oper->top_oper >= 0){
        pop_oper(p_oper, &temp);
        p->post_str[i++] = temp;
    }
    p->post_str[i] = '\0';
    free(p_oper); // 释放符号栈
}

void compute_value(Node * p){
    DataStack * p_data = (DataStack *)calloc(1, sizeof(DataStack)); // 定义一个操作数栈,并初始化
    p_data->top_data = -1;
    double temp1, temp2, num, res;
    int i = 0;
    char temp3[MAXSIZE];
    char * pcur = p->post_str;
    while(* pcur != '\0'){
        switch(* pcur){
        case '+':
            pop_data(p_data, &temp1);
            pop_data(p_data, &temp2);
            res = temp2 + temp1;
            push_data(p_data, res);
            break;
        case '-':
            pop_data(p_data, &temp1);
            pop_data(p_data, &temp2);
            res = temp2 - temp1;
            push_data(p_data, res);
            break;
        case '*':
            pop_data(p_data, &temp1);
            pop_data(p_data, &temp2);
            res = temp2 * temp1;
            push_data(p_data, res);
            break;
        case '/':
            pop_data(p_data, &temp1);
            pop_data(p_data, &temp2);
            if(temp1 != 0){
                res = temp2 / temp1;
                push_data(p_data, res);
                break;
            }else{
                printf("\n除零错误!\n");
                exit(0);
            }
            break;
        default:
            num = 0;
            while((* pcur >= '0' && * pcur <= '9') || * pcur == '.'){
                temp3[i++] = * pcur;
                pcur++;
            }
            temp3[i] = '\0';
            num = atof(temp3); // 将数字串转换成浮点数
            i = 0;
            push_data(p_data, num);
            break;
        }
        pcur++;
    }
    get_top_data(p_data, &(p->res));
    return;
}

void push_oper(SqStack * p_oper, char ch){
    if(p_oper->top_oper == MAXSIZE - 1){
        printf("The operator stack is full!\n");
    }else{
        p_oper->top_oper++;
        p_oper->oper[p_oper->top_oper] = ch;
    }
    return;
}

void pop_oper(SqStack * p_oper, char * ch){
    if(p_oper->top_oper < 0){
        printf("The operator stack is empty!\n");
    }else{
        * ch = p_oper->oper[p_oper->top_oper];
        p_oper->top_oper--;
    }
    return;
}

void get_top_oper(SqStack * p_oper, char * ch){ // 取栈顶元素,但不移动栈顶指针
    if(p_oper->top_oper < 0){
        printf("The operator stack is empty!\n");
    }else{
        * ch = p_oper->oper[p_oper->top_oper];
    }
    return;
}

void push_data(DataStack * p_data, double num){
    if(p_data->top_data == MAXSIZE - 1){
        printf("The data stack is full!\n");
    }else{
        p_data->top_data++;
        p_data->data[p_data->top_data] = num;
    }
    return;
}

void pop_data(DataStack * p_data, double * num){
    if(p_data->top_data < 0){
        printf("The data stack is empty!\n");
    }else{
        * num = p_data->data[p_data->top_data];
        p_data->top_data--;
    }
    return;
}

void get_top_data(DataStack * p_data, double * num){
    if(p_data->top_data < 0){
        printf("The data stack is empty!\n");
    }else{
        * num = p_data->data[p_data->top_data];
    }
    return;
}

void list_tail_insert(Node ** pphead, Node ** pptail, Node * p){
    if(* pphead == NULL){
        * pphead = p;
        * pptail = p;
    }else{
        (* pptail)->pnext = p;
        * pptail = p;
    }
    return;
}

void list_print(Node * phead){
    while(phead != NULL){
        printf("\nres = %.1lf", phead->res);
        phead = phead->pnext;
    }
    return;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值