数据结构实现中缀表达式到后缀表达式,再到计算出结果的代码

来源:互联网 发布:大数据中学生阅读答案 编辑:程序博客网 时间:2024/06/07 18:24
#include <stdio.h>
#include <stdlib.h>
struct node
{
    int data;
    struct node *next;
};
typedef struct node *stack;
stack initStack()
{
    stack s=(stack)malloc(sizeof(struct node));
    s->next=NULL;
    return s;
}
int isEmpty(stack s)
{
    return s->next==NULL;
}
void push(stack s,int x)
{
    stack p=(stack)malloc(sizeof(struct node));
    p->data=x;
    p->next=s->next;
    s->next=p;
}
void pop(stack s,int *x)
{
    stack p=s->next;
    if(isEmpty(s))
    {
        printf("Stack is empty!\n");
        return;
    }
    s->next=p->next;
    *x=p->data;
    free(p);
}
int getTop(stack s)
{
    return s->next->data;//返回栈底的节点的data的值
}






int ExpCorrect(char exp[],int n)
{
    int i;
    stack s=initStack();
    for(i=0; i<n; i++)
    {
        if(exp[i]=='('||exp[i]=='[')
            push(s,exp[i]);
        else if(exp[i]==')'||exp[i]==']')
        {
            int x;
            if(isEmpty(s))  return 0;
            pop(s,&x);
            if(exp[i]==')'&&x!='(')
                return 0;
            if(exp[i]==']'&&x!='[')
                return 0;
        }
    }
    if(isEmpty(s)) return 1;
    else return 0;
}
int Palindrome(char str[],int n)
{
    char *p=str;
    stack s=initStack();
    for(; p<str+n/2; p++)
        push(s,*p);
    if(n%2)    p++;
    while(*p!='\0')
    {
        int x;
        pop(s,&x);
        if(x!=*p)
            return 0;
        p++;
    }
    return 1;
}
//判断是否为运算符
int isOper(char c)
{
    switch(c)
    {
    case '+':
    case '-':
    case '*':
    case '/':
    case '(':
    case ')':
    case '#':
        return 1;
        break;//是运算符就返回1
    default :
        return 0;//不是就返回0
    }


}




//比较栈内和栈外的优先级c1内 c2外
char compare(char c1,char c2)
{
    //先定义两个变量,用来表示优先级别
    int a,b;
    //对栈内的a进行复制
    switch(c1)
    {
    case '#':
        a=-1;
        break;
    case '(':
        a=0;
        break;
    case '+':
    case '-':
        a=2;
        break;
    case '*':
    case '/':
        a=4;
        break;
    }
    //对栈外的b进行复制
    switch(c2)
    {
    case '#':
        b=-1;
        break;
    case '(':
        b=5;
        break;
    case ')':
        b=0;
        break;
    case '+':
    case '-':
        b=1;
        break;
    case '*':
    case '/':
        b=3;
        break;
    }
    if(a>b)
    {
        return '>';
    }
    if(a==b)
    {
        return '=';
    }
    if(a<b)
    {
        return '<';
    }
}


//计算x op y的结果两个操作数的结果
int twoResult(char op,int x,int y)
{
    int z;
    switch(op)
    {
    case '+':
        z=x+y;
        break;
    case '-':
        z=x-y;
        break;
    case '/':
        z=x/y;
        break;
    case '*':
        z=x*y;
        break;
    }
    return z;
}


//中缀表达式转化为后缀表达式
char *changeToback(char str[])
{
    char *str2=(char *)malloc(sizeof(char)*100);
    stack s=initStack();
    int i=0,j=0,x;//中缀变后缀要两个指向x用来存放出战的数据元素
    push(s,'#');//先存入#作为之后的有关的判断
    strcat(str,"#");//将#链接到原来的表达式中
    while(getTop(s)!='#'||str[i]!='#')
    {


        if(!isOper(str[i]))
        {
            str2[j++]=str[i++];
        }
        else
        {
            str2[j++]='?';
            switch(compare(getTop(s),str[i])) //求出栈顶内和栈外的进行比较
            {


            case '>':
                pop(s,&x);
                str2[j++]=x;
                break;//出栈,保存到str2这个数组之中
            case '=':
                pop(s,&x);
                i++;
                break;//出栈不输出
            case '<':
                push(s,str[i++]);
                break;//入栈
            }
        }
    }
    str2[j]='\0';
    return str2;
}


//后缀表达式求值
int expressResult(char *p)
{
    int sum=0,cot=0;
    char *q=p;
    int previous;
    int next;
    int count=0;
    stack s=initStack();//初始化栈对象
//    while(*p!='\0')//当p指向的是一个'\0'的时候代表便利完成
//    {
//
//        if(*p<=55&&*p>=48) //当指向的值不是符号的时侯将数字存入到栈内存中
//        {
//            //先尽行数据的类型转化
//            *p=*p-48;
//            push(s,*p);
//        }
//        else
//        {
//            if(count==0)
//            {
//                pop(s,&next);
//                sum=next;   //将第一个next的值赋值给sum
//                count++;
//            }
//            pop(s,&previous);
//            sum=twoResult(*p,sum,previous);
//        }
//        p++;
//
//    }
//    return sum;
    while(*p!='\0')
    {
        if(*p<=57&&*p>=48&&*p!='?') //当指向的值不是符号的时侯将数字存入到栈内存中
        {
            //先尽行数据的类型转化
            cot=cot*10+(*p-48);//得到当前的数据
            q=p+1;//判断下一个是否为?
            if(*q=='?')
            {
                push(s,cot);
                cot=0;//将cot重置为0,方便下一次存储
            }
        }
        else if(*p!='?')
        {
//            if(count==0)
//            {
//                pop(s,&next);
//                sum=next;   //将第一个next的值赋值给sum
//                count++;
//            }
//            pop(s,&previous);
//            sum=twoResult(*p,sum,previous);
            pop(s,&previous);
            pop(s,&next);
            sum=twoResult(*p,next,previous);
            push(s,sum);
        }
        p++;
    }
    return sum;
}










int main()
{
//    char str[100];
//    while(1)
//    {
//        gets(str);
//        if(Palindrome(str,strlen(str)))
//            puts("Yes!");
//        else
//            puts("No!");
//    }
    int value;
    char str[100],*p,*cont;
    while(1)
    {
        gets(str);
        p=changeToback(str);
        cont=p;//这个指针用来便利,若直接使用p后面会抛出空指针异常
        for(;*cont!='\0';cont++){
                if(*cont=='?'||*cont=='#') continue;
            printf("%c",*cont);
        }
        printf("\n");
//        puts(p);
        value=expressResult(p);
        printf("%d",value);


    }
    return 0;
}

0 0
原创粉丝点击