关于用栈链表来实现中序表达式的一个小程序 《数据结构》
2013-08-14 20:29
453 查看
今天我在黄国瑜的《数据结构》一书中看到一段代码:于用栈链表来实现中序表达式,代码如下:
执行时有一个警告:
![](http://img.blog.csdn.net/20130814200637218?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2RsY3dhbmdzb25n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
查资料知在gcc编译器中没有gets函数,只有fgets,在这里为了结果的正确就不改了。这样也可以执行。
可是呢,在执行的时候,当你执行1+1,2*3,1+2*3,等等类似的表达式都是正确的,可是当执行1+1+1,2*3+1这样的时候就出现段错误,为什么呢?分析表达式,看出只要是前面的运算符小于后边的运算符时都是正确的,大于等于时都错了。
后来经过调试,发现第87行改为这样就对了:
之前:
改后:while(!empty(operator)&&priority(expression[position])<=priority(operator->data))
因为当输入运算符时要进行与上一次运算符的比较,如果这次的运算符优先级高于上一次的话,就执行下面的语句,执行完语句后,再次进行判断优先级,按照未改之前的看,当执行到priority(operator->data)时就出错了,因为i这时operator就是空了,它没有data了,所以出现了段错误。把empty(operator)提到前面来,进来后直接判断,为空直接执行while之外的语句,这样就对了。
(后记:虽然刚刚接触gdb,可是真好用,这次就是用它找到段错误的,要不是用它,不知道又得折腾到什么时候呢!)
#include <stdio.h> #include <stdlib.h> #include <stdlib.h> struct s_node { int data; struct s_node *next; }; typedef struct s_node s_list; typedef s_list *link; link operator=NULL; link operand=NULL; link push(link stack,int value) { link newnode; newnode=(link)malloc(sizeof(s_list)); if(!newnode){ printf("\nMemory allocation failure!"); return NULL; } newnode->data=value; newnode->next=stack; stack=newnode; return stack; } link pop(link stack,int *value) { link top; if(stack!=NULL){ top=stack; stack=stack->next; *value=top->data; free(top); return stack; } else *value=-1; } int empty(link stack) { if(stack==NULL) return 1; else return 0; } int is_operator(char operator) { switch(operator){ case '+': case '-': case '*': case '/': return 1; default:return 0; } } int priority(char operator) { switch(operator){ case '+':case '-':return 1; case '*':case '/':return 2; default: return 0; } } int two_result(int operator,int operand1,int operand2) { switch(operator){ case '+':return (operand2+operand1); case '-':return (operand2-operand1); case '*':return (operand2*operand1); case '/':return (operand2/operand1); } } void main() { char expression[50]; int position=0; int op=0; int operand1=0; int operand2=0; int evaluate=0; printf("\nPlease input the inorder expression:"); gets(expression); while(expression[position]!='\0'&&expression[position]!='\n'){ if(is_operator(expression[position])){ if(!empty(operator)) while(priority(expression[position])<=priority(operator->data)&&!empty(operator)){ operand=pop(operand,&operand1); operand=pop(operand,&operand2); operator=pop(operator,&op); operand=push(operand,two_result(op,operand1,operand2)); } operator=push(operator,expression[position]); } else operand=push(operand,expression[position]-48); position++; } while(!empty(operator)){ operator=pop(operator,&op); operand=pop(operand,&operand1); operand=pop(operand,&operand2); operand=push(operand,two_result(op,operand1,operand2)); } operand=pop(operand,&evaluate); printf("The expression[%s]result is '%d'\n",expression,evaluate); }
执行时有一个警告:
查资料知在gcc编译器中没有gets函数,只有fgets,在这里为了结果的正确就不改了。这样也可以执行。
可是呢,在执行的时候,当你执行1+1,2*3,1+2*3,等等类似的表达式都是正确的,可是当执行1+1+1,2*3+1这样的时候就出现段错误,为什么呢?分析表达式,看出只要是前面的运算符小于后边的运算符时都是正确的,大于等于时都错了。
后来经过调试,发现第87行改为这样就对了:
之前:
while(priority(expression[position])<=priority(operator->data)&&!empty(operator))
改后:while(!empty(operator)&&priority(expression[position])<=priority(operator->data))
因为当输入运算符时要进行与上一次运算符的比较,如果这次的运算符优先级高于上一次的话,就执行下面的语句,执行完语句后,再次进行判断优先级,按照未改之前的看,当执行到priority(operator->data)时就出错了,因为i这时operator就是空了,它没有data了,所以出现了段错误。把empty(operator)提到前面来,进来后直接判断,为空直接执行while之外的语句,这样就对了。
(后记:虽然刚刚接触gdb,可是真好用,这次就是用它找到段错误的,要不是用它,不知道又得折腾到什么时候呢!)
相关文章推荐
- 链表翻转。给出一个链表和一个数k,比如链表1→2→3→4→5→6,k=2,则翻转后2→1→4→3→6→5,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→5→6,用程序实现
- 利用模板类编写一个程序,实现双向链表的插入、删除、查找、显示的功能。
- 用PHP实现一个关于德州扑克算法的程序(三):顺子
- 关于实现Comparable接口的一个小程序
- 链表翻转。给出一个链表和一个数k,比如链表1→2→3→4→5→6,k=2,则翻转后2→1→4→3→6→5,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→5→6,用程序实现
- 数据结构复习 之 一个简单双向链表的实现
- 【数据结构】中序线索化二叉树后实现一个迭代器来遍历二叉树
- (学习java)写一个完整的程序,实现随机生成20个元素的链表,快速查找中间结点的值并显示
- 一连浪了好几天了,一直没好好的学习,希望在运动会结束后能够好好的认真学习,下面是关于栈的链表形式的有关函数的实现,与上一个实现形式有所差别
- 9月10日,美团网2014校招研发笔试哈尔滨站 1、链表翻转。给出一个链表和一个数k,比如链表1→2→3→4→5→6,k=2,则翻转后2→1→4→3→6→5,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→5→6,用程序实现
- 用PHP实现一个关于德州扑克算法的程序(二):排序
- 用PHP实现一个关于德州扑克算法的程序(一):发牌
- 关于怎么让多个程序搭建在一个服务器上,搭建一个适合与架构师使用的开发与实现环境
- 用PHP实现一个关于德州扑克算法的程序(四):代码
- 用链表实现的一个小程序(C语言)
- 小蚂蚁学习数据结构(27)——题目——一个关于链表的题目
- 编写一个程序,实现删除链表中倒数第k个节点(用单链表实现)
- 数据结构中关于链表的一个简单问题
- 数据结构--单链表基本功能实现程序…
- 借助 数组 实现一个关于大整数乘法的 c 程序