您的位置:首页 > 理论基础 > 数据结构算法

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

2017-04-17 16:12 711 查看
#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 '(':

abe0
        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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: