思路 将中缀表达式转化为后缀表达式处理 

数据结构 栈

注 目前只适用 10以内的带括号的 +-*/^ 运算

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

#define ElementType char
#define ERROR -1

// 定义栈的结构
typedef struct SNode *PtrToSNode;
struct SNode{
    ElementType Data;
    PtrToSNode Next;
};
typedef PtrToSNode Stack;

// 定义链表的结构
typedef struct LNode *PtrToLNode;
struct LNode{
    ElementType Data;
    PtrToLNode Next;
};
typedef PtrToLNode List;
typedef PtrToLNode Position;
// 定义一个头节点 Next指的头节点下一个节点 Last指的链表最后一个节点
typedef struct LHeadNode *LHead;
struct LHeadNode{
    ElementType Data;
    PtrToLNode Next;
    Position Last;
};

// 定义一个数据为double的栈 用于计算
typedef struct SDoubleNode *PtrToSDoubleNode;
struct SDoubleNode{
    double Data;
    PtrToSDoubleNode Next;
};
typedef PtrToSDoubleNode DoubleStack;

Stack CreateStack(void){ // 带头节点的栈
    Stack S;
    S = (Stack)malloc(sizeof(struct SNode));
    S->Next = NULL;
    return S;
}

bool IsEmpty(Stack S){
    return (S->Next == NULL);
}

bool Push(Stack S, ElementType X){
    PtrToSNode q;
    q = (PtrToSNode)malloc(sizeof(struct SNode));
    q->Data = X;
    q->Next = S->Next;
    S->Next = q;
    return true;
}

ElementType Pop(Stack S){
    PtrToSNode FirstCell;
    ElementType TopElem;
    
    if(IsEmpty(S)){
        printf("Stack is Empty\n");
        return ERROR;
    }else{
        FirstCell = S->Next;
        TopElem = FirstCell->Data;
        S->Next = FirstCell->Next;
        free(FirstCell);
        return TopElem;
    }
}

LHead CreateList(void){   // 创造带头节点的链表
    LHead L = (LHead)malloc(sizeof(struct LHeadNode));
    L->Next = NULL;
    L->Last = NULL;
    return L;
}

int ListIsEmpty(LHead L){ // 判断链表是否为空 是 返回1 否则返回0
    if(L->Last == NULL)
        return 1;
    return 0;
}

void TailInsert(LHead L,ElementType X){ //链表尾部插入
    PtrToLNode p = (PtrToLNode)malloc(sizeof(struct LNode));
    p->Data = X;
    p->Next = NULL;
    if(ListIsEmpty(L)){
        L->Next = p;
        L->Last = p;
    }else{
        L->Last->Next = p;
        L->Last = p;
    }
}

void TavelList(LHead L){
    Position p = L->Next;
    while (p) {
        printf("%c ",p->Data);
        p = p->Next;
    }
    printf("\n");
}

DoubleStack CreateDoubleStack(void){ // 带头节点的栈
    DoubleStack S;
    S = (DoubleStack)malloc(sizeof(struct SDoubleNode));
    S->Next = NULL;
    return S;
}

bool DoubleStackIsEmpty(DoubleStack S){
    return (S->Next == NULL);
}

bool DoubleStackPush(DoubleStack S, double X){
    DoubleStack q;
    q = (DoubleStack)malloc(sizeof(struct SDoubleNode));
    q->Data = X;
    q->Next = S->Next;
    S->Next = q;
    return true;
}

double DoubleStackPop(DoubleStack S){
    DoubleStack FirstCell;
    double TopElem;
    
    if(DoubleStackIsEmpty(S)){
        printf("Stack is Empty\n");
        return ERROR;
    }else{
        FirstCell = S->Next;
        TopElem = FirstCell->Data;
        S->Next = FirstCell->Next;
        free(FirstCell);
        return TopElem;
    }
}
/*给出运算符给出优先级 优先级越大 则返回值越大
 +- --> 1
 / * --> 2
 ^ --> 3
 ( 在入栈前为4 在栈中为0 用tag记是否在栈中 1代表是 0代表不是
 */
int CaculatePriority(char c,int tag){
    if(c == '+' || c == '-'){
        return 1;
    }else if(c == '/' || c == '*'){
        return 2;
    }else if (c == '^'){
        return 3;
    }else{
        if(tag == 0){
            return 4;
        }else{
            return 0;
        }
    }
}

LHead ChangeExpression(void){  //将中缀表达式转化为后缀表达式
    char c,t;  // c 输入元素 t 栈中符号
    int c1,t1; // c1 输入符号优先级 s 栈中符号优先级
    Stack s = CreateStack(); // 存符号的临时栈
    LHead l = CreateList(); // 存后缀表达式的链表
    scanf("%c",&c);
    while (c!='\n') {
        if(c <= '9' && c >= '0'){
            TailInsert(l, c);
        }else{
            if(IsEmpty(s)){
                Push(s, c);
            }else if(c == ')'){
                t = Pop(s);
                while (t != '(') {
                    TailInsert(l, t);
                    t = Pop(s);
                }
            }else{
                c1 = CaculatePriority(c, 0);
                t = s->Next->Data;
                t1 = CaculatePriority(t, 1);
                if(c1 > t1){
                    Push(s, c);
                }else{
                    do{
                        t = Pop(s);
                        TailInsert(l, t);
                        if(IsEmpty(s)){
                            break;
                        }
                        t = s->Next->Data;
                        t1 = CaculatePriority(t, 1);
                    }while(c1 <= t1);
                    Push(s, c);
                }
            }
        }
        scanf("%c",&c);
    }
    t = Pop(s);
    TailInsert(l, t);
    return l;
}

double CaculateExpresion(LHead L){ // 计算后缀表达式
    Position p = L->Next;
    DoubleStack s = CreateDoubleStack();
    double a,b,t;
    while (p!=NULL) {
        if(p->Data <= '9' && p->Data >= '0'){
            t = p->Data - '0';
            DoubleStackPush(s, t);
        }else if (p->Data == '+'){
            a = DoubleStackPop(s);
            b = DoubleStackPop(s);
            t = b + a;
            DoubleStackPush(s, t);
//            printf("%.2lf + %.2lf = %.2lf\n",b,a,t);
        }else if (p->Data == '-'){
            a = DoubleStackPop(s);
            b = DoubleStackPop(s);
            t = b - a;
            DoubleStackPush(s, t);
 //           printf("%.2lf - %.2lf = %.2lf\n",b,a,t);
        }else if (p->Data == '*'){
            a = DoubleStackPop(s);
            b = DoubleStackPop(s);
            t = b * a;
            DoubleStackPush(s, t);
//            printf("%.2lf * %.2lf = %.2lf\n",b,a,t);
        }else if (p->Data == '/'){
            a = DoubleStackPop(s);
            b = DoubleStackPop(s);
            t = b / a;
            DoubleStackPush(s, t);
 //           printf("%.2lf / %.2lf = %.2lf\n",b,a,t);
        }else if (p->Data == '^'){
            a = DoubleStackPop(s);
            b = DoubleStackPop(s);
            t = pow(b, a);
            DoubleStackPush(s, t);
 //           printf("%.2lf ^ %.2lf = %.2lf\n",b,a,t);
        }
        p = p->Next;
    }
    t = DoubleStackPop(s);
    return t;
}

int main(){
    LHead l = ChangeExpression();
    TavelList(l);
    double s;
    s = CaculateExpresion(l);
    printf("%.2lf",s);
    return 0;
}

 

posted on 2022-11-12 21:51  Rabbit_XIN  阅读(50)  评论(0)    收藏  举报