关闭

前缀变后缀

标签: 计算机科学数据结构源代码
340人阅读 评论(0) 收藏 举报
分类:


 

一、实验目的

1. 掌握栈的数据结构与基本操作(链表和数组实现栈)

2. 了解什么是中缀表达式和后缀表达(逆波兰表达式)

3. 掌握中缀表达式转为后缀表达式的方法

4. 掌握使用栈结构计算后缀表达式

5. 提高利用计算机分析和解决复杂实际问题的能力

6. 锻炼自己的编程能力和查阅资料的能力

二、实验要求及实验环境

实验要求:

1.从键盘输入任意一个语法正确的(中缀)表达式,显示并保存该表达式。

 

2.利用栈结构,把上述(中缀)表达式转换成后缀表达式,并显示栈的状态变化过程和所得到的后缀表达式。

 

3.利用栈结构,对上述后缀表达式进行求值,并显示栈的状态变化过程和最终结果。

实验环境:

1.Windows 7操作系统

 

2.GC++ 编译器

 

 

三、设计思想(本程序中的用到的所有数据类型的定义,主程序的流程图及各程序模块之间的调用关系)

struct node{            //定义栈--链表实现

    float num; //存放操作数

    char data; //存放操作符

    struct node *next;

};

函数列表:

 

Stack CreateStack( void )          //创建一个带表头的空栈

int IsEmpty( Stack s )             //判断是否为空栈

void MakeEmpty( Stack s )        //将栈变空

Stack Transform( Stack s )         //输入和转换

void Pop(Stack s)   //弹出栈顶

void Calculate(Stack s)            //计算并输出结果

//定义全局变量

char string1[100];         //存储中缀表达式

char string2[100];         //存储后缀表达式

char flag[100];             

五、系统不足与经验体会

1.(1)不能计算(-(12+23))*2这样的算式。

(2)使用栈时比较浪费存储空间,最好使用联合体union来写能够节省一半的空间。

(3)将字符串转化为实数时调用了atof函数,没有自己编写函数。

2.(1)在编写代码时,要思路清晰,设计要严谨,考虑问题要全面。

(2)要学会查阅资料,上网查询时它不一定正确,要学会            判断正误。

(3)多与别人讨论问题并且交换思路,不能自己空想,很浪费时间和精力。

 

六、附录:源代码(带注释)

 

/********************************************/

/* 中缀表达式变为后缀表达式并计算输入结果   */

/* 1120310510 高天峰 计科五班               */

/*日期: 2013 .10. 25                       */

/*修改: 10 .29                             */

/********************************************/

 

#include<stdio.h>

#include<malloc.h>

#include<string.h>

#include<stdlib.h>

//定义全局变量

char string1[100];      //存储中缀表达式

char string2[100];      //存储后缀表达式

char flag[100];         //设置标志符号

int j=0;

 

 

struct node{            //定义栈--链表实现

    float num;

    char data;

    struct node *next;

};

typedef struct node * Stack;

 

Stack CreateStack( void )           //创建一个带表头的空栈

{

    Stack s;

    s = malloc( sizeof ( struct node ) );

    if ( s == NULL )

    {

        printf("申请内存失败!!程序已退出!!\n");

        exit(1);

    }

    s->num = 0;

    s->data = '@';                  //  设置数组标识符

    s->next = NULL;

    return s;

}

 

int IsEmpty( Stack s )              //判断是否为空栈

{

    return s -> next == NULL;

}

void Pop(Stack s)

{

   Stack stk;

   if(s->next){

    stk=s->next;

    s->next=stk->next;

    free(stk);

   }

}

 

void MakeEmpty( Stack s )            //将栈变空

{

    if ( s == NULL )

    {

        printf("请先使用CreateStack函数!!\n");

    }

    else

        while( !IsEmpty ( s ) )

            Pop ( s );

}

 

Stack Transform( Stack s )                 //输入中缀表达式并输出后缀表达式

{

    Stack p,top;

int i;

int m;

char a;

top=s;

gets(string1);

m=strlen(string1);                  //数组长度

for(i=0;i<m;i++)

    {

         if(string1[i] == '(' && string1[i+1]=='-')

           {

               string2[j] = string1[i+1];

                flag[j] = 1; //设置负数标志位

                j++;

                i=i+2;

                while ( string1[i] != ')' )

                {

 

                    string2[j]=string1[i];

                    flag[j]=0;

                    j++;

                    i++;

                }

 

           }

           else{

                    if ( ('0' <= string1[i] && string1[i] <= '9' )|| string1[i] == '.')

                    {

                        string2[j]=string1[i];

                        flag[j]=0;

                        j++;

                    }

                    else {

                        a=string1[i];

                        switch(a)

                        {

                            case '(':{

                                     p=malloc(sizeof(struct node));

                                     p->data=a;

                                     p->next=top;

                                     top=p;

                                     printf("将‘(’入栈。\n");

                                     break;

                                     }

                            case '*':

                            case '/':

                                {

                                   string2[j]=' ';flag[j]=0;

                                   j++;

                                    if((top->data=='*')||(top->data=='/'))

                                    {

                                        printf("将‘%c’出栈。\n",top->data);

                                        string2[j]=top->data;//比其高,现将栈顶运算符出栈,再进栈。

                                        flag[j]=0;

                                        j++;

                                        top->data=a;

                                        printf("将‘%c’入栈。\n",top->data);

                                        break;

                                    }

                                    else

                                    {

                                        p=malloc(sizeof(struct node));//否,直接进栈

                                        p->data=a;

                                        p->next=top;

                                        top=p;

                                        printf("将‘%c’入栈。\n",a);

                                        break;

                                    }

 

                                }

                            case '+':

                            case '-':

                                {

                                    string2[j]=' ';flag[j]=0;

                                    j++;

                                    if(top->data=='+'||top->data=='-'||top->data=='*'||top->data=='/')

                                    {

                                        printf("将‘%c’出栈。\n",top->data);

                                        string2[j]=top->data;

                                        flag[j]=0;

                                        j++;

                                        if(top->next->data=='+'||top->next->data=='-')

                                        {

                                            top=top->next;

                                            string2[j]=top->data;

                                            flag[j]=0;

                                            printf("将‘%c’出栈。\n",top->data);

                                        }

                                        top->data=a;

                                        printf("将‘%c’入栈。\n",top->data);

                                        j++;

                                    }

                                    else{

                                        p=malloc(sizeof(struct node));//否,直接进栈

                                        p->data=a;

                                        p->next=top;

                                        top=p;

                                        printf("将‘%c’入栈。\n",top->data);

                                    }

                                    break;

                                }

                            case ')':

                                {

                                    while(top->data != '(')

                                            {

                                                string2[j]=top->data;

                                                printf("将‘%c’出栈。\n",top->data);

                                                flag[j]=0;

                                                j++;

                                                p=top;

                                                top = top->next;

                                                free(p);

                                            }

                                    p=top;

                                    printf("将‘%c’出栈,并删除。\n",top->data);

                                    top = top->next;

                                    free(p);

                                }

                        }

                    }

    }}

    while(top->data!='@')  //判断标志位

    {

        string2[j]=top->data;

        printf("将‘%c’出栈。\n",top->data);

        flag[j]=0;

        j++;

        p=top;

        top=top->next;

        free(p);

    }

    string2[j]='#'; //设置最后标志位

    printf("转化后的后缀表达式为:%s\n",string2);

return top;

}

 

void Calculate(Stack s)             //利用后最表达式来计算并输出结果

{

    int i,n;

    float q,x,y,z;

    char a;

    Stack top,p;

    top = s;

    for( i=0;i <= j; i++)

    {

        if(flag[i]==1) //判断是否为负数

        {

                q = atof( &string2[i] ); //将字符串转化为浮点数

                for(n=i+1;(string2[n]>='0'&&string2[n]<='9')||string2[n]=='.';n++){}

                p=malloc(sizeof(struct node));

                p->num = q;

                p->next = top;

                top=p;

                printf("将‘%f’入栈。\n",top->num);

                i=n-1;

        }

        else{ //不是负数时

                if(string2[i] >= '0'&& string2[i] <= '9')

                {

                    q = atof( &string2[i]);         //将字符串转化为浮点数

                    for(n=i;(string2[n]>='0'&&string2[n]<='9')||string2[n]=='.';n++){}

                    p=malloc(sizeof(struct node));

                    p->num = q;

                    p->next = top;

                    top=p;

                    printf("将‘%f’入栈。\n",top->num);

                    i=n-1;

                }

                else

                {

                        if(string2[i] == '#')

                        printf("后缀表达式计算结果是:%f\n",top->num);

                    else

                    {

                        if(string2[i]==' '){}

                        else{

                        y=top->num;printf("将‘%f’出栈。\n",top->num);p=top;top=top->next;free(p);

                        x=top->num;printf("将‘%f’出栈。\n",top->num);p=top;top=top->next;free(p);

                        a = string2[i];

                        switch(a)

                        {

                            case '+':{

                                    z=x+y;

                                   break;}

                            case '-':{

                                    z=x-y;

                                  break;}

                            case '*':{

                                z=x*y;

                                  break;}

                            case '/':{

                                    z=(float)x/y;

                                    if(y == 0)

                                        {

                                            printf("除数为0程序中断,请检查后再重新输入!!\n");

                                            exit(1);

                                        }

                                    else

                                    break;}

                            }

                        p=(struct node *)malloc(sizeof(struct node ));

                        p->num=z;

                        p->next=top;

                        top=p;

                        printf("将‘%f’入栈。\n",top->num);

                    }

                }

                }

    }

    }

}

 

//主程序

int main()

 

{

 

    Stack top,head;

top=CreateStack(); //建立一个链栈,并返回栈顶指针

printf("程序说明:\n");

    printf("一、功能:输出后缀表达式并输出结果.\n");

    printf("二、注意:\n");

    printf("        1.注意在输入时请切到英文输入法输入.\n");

    printf("        2.输入负数时请加(),如(-12).\n");

    printf("        3.可以计算小数,可判断除数是否为0.\n");

    printf("请输入前缀表达式:\n");

head=Transform(top); //中缀转化为后缀表达式

Calculate(head); //后缀表达式的计算

return 0;

 

}

 


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:971次
    • 积分:43
    • 等级:
    • 排名:千里之外
    • 原创:3篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档