利用栈实现的经典案例
来源:互联网 发布:园林效果图设计软件 编辑:程序博客网 时间:2024/06/02 04:09
1.用栈来实现任意进制进制转换
//linklist.h
#ifndef __LINKLIST_H__#define __LINKLIST_H__typedef struct linklistnode { struct linklistnode *next; int item;}LinkListNode; //数据节点 typedef struct linklist { LinkListNode header; int length;}LinkList; //头节点 LinkList *LinkList_Create();void LinkList_Destroy(LinkList *list);void LinkList_Clear(LinkList *list);int LinkList_Length(LinkList *list);int LinkList_Insert(LinkList *list, LinkListNode *node, int pos);LinkListNode *LinkList_Get(LinkList *list,int pos);LinkListNode *LinkList_Delete(LinkList *list,int pos);#endif //__LINKLIST_H__
//linklist.c
#include <stdlib.h>#include "linklist.h"LinkList *LinkList_Create(){ LinkList *ret = NULL; ret = malloc(sizeof(LinkList)); if(ret!=NULL) { ret->length = 0; ret->header.next = NULL; } return ret;}void LinkList_Destroy(LinkList *list){ free(list);}void LinkList_Clear(LinkList *list){ if(list!=NULL) { list->length =0; list->header.next = NULL; }}int LinkList_Length(LinkList *list){ int ret = -1; if( list!=NULL ) { ret = list->length; } return ret;}int LinkList_Insert(LinkList *list, LinkListNode *node, int pos){ int ret = list!=NULL && node!=NULL && pos>=0; if( ret ) { int i; LinkListNode *cur = (LinkListNode *)list; for(i=0;i<pos && cur->next!=NULL;i++) { cur = cur->next; } node->next = cur->next; cur->next = node; list->length++; } return ret;}LinkListNode *LinkList_Get(LinkList *list,int pos){ LinkListNode *ret = NULL; if( list!=NULL && (0<=pos && pos<list->length) ) { int i; LinkListNode *cur = (LinkListNode *)list; for(i=0; i<pos; i++) cur = cur->next; ret = cur->next; //因为从0开始计数的,要第三个数,那么就是第二个数的next } return ret;}LinkListNode *LinkList_Delete(LinkList *list,int pos){ LinkListNode *ret = NULL; if(list!=NULL && (0<=pos&&pos<list->length) ) { int i; LinkListNode *cur = (LinkListNode *)list; for(i=0; i<pos; i++) cur = cur->next; ret = cur->next; //单项链表是从0开始排的。 cur->next = ret->next; list->length--; } return ret;}
//linkstack.h
#ifndef __LINKSTACK_H__#define __LINKSTACK_H__typedef struct linkstacknode{ struct linkstacknode *node; void *item;}LinkStackNode;typedef void LinkStack;LinkStack *LinkStack_Create();void LinkStack_Destroy(LinkStack *stack);void LinkStack_Clear(LinkStack *stack);int LinkStack_Push(LinkStack *stack,void *item);void *LinkStack_Pop(LinkStack *stack);void *LinkStack_Top(LinkStack *stack);int LinkStack_Size(LinkStack *stack);#endif //__LINKSTACK_H__
//linkstack.c
#include <stdio.h>#include <stdlib.h>#include <string.h>#include "linklist.h"#include "linkstack.h"LinkStack *LinkStack_Create(){ return LinkList_Create();}void LinkStack_Destroy(LinkStack *stack){ LinkStack_Clear(stack); LinkList_Destroy(stack);}void LinkStack_Clear(LinkStack *stack){ while ( LinkStack_Size(stack) > 0 ) LinkStack_Pop(stack);}int LinkStack_Push(LinkStack *stack,void *item){ LinkStackNode *node = malloc(sizeof(LinkStackNode)); int ret = stack!=NULL && item!=NULL && node!=NULL; if( ret ) { memset(node,0x00,sizeof(*node)); //?? node->item = item; ret = LinkList_Insert(stack, (LinkListNode *)node, 0); } if(!ret) { free(node); } return ret;}void *LinkStack_Pop(LinkStack *stack){ LinkStackNode *node = NULL; void *ret = NULL; node = (LinkStackNode *)LinkList_Delete(stack,0); if ( node != NULL) { ret = node->item; free(node); } return ret;}void *LinkStack_Top(LinkStack *stack){ LinkStackNode *node = NULL; void *ret = NULL; node = (LinkStackNode *)LinkList_Get(stack,0); if( node!=NULL) { ret = node->item; } return ret;}int LinkStack_Size(LinkStack *stack){ return LinkList_Length(stack);}
//main.c
#include <stdio.h>#include <stdlib.h>#include "linkstack.h"void convert(int digit,int base){ static char num[]= {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; LinkStack *stack = LinkStack_Create(); do { LinkStack_Push(stack,&num[digit%base]); //进栈 digit /= base; }while( digit!= 0 ); while ( LinkStack_Size(stack) > 0 ) { char *c = (char *)LinkStack_Pop(stack); //出栈 printf("%c", *c); } printf("\n"); LinkStack_Destroy(stack);}int main( void ){ convert(10,2); //十进制的10转换为2进制 convert(32,16); //十进制的转换为16进制 return 0;}
Makefile
cc :=gccmain : main.o linklist.o linkstack.o gcc $^ -o $@.PHONY : main cleanclean: rm -rf *.o main
2.用栈来实现加、减、乘、除的计算
中缀转后缀
对于数字,直接输出 对于符号: 左括号:进栈 符号:于栈顶符号进行优先级比较 栈顶优先级低:进栈 栈顶优先级不低,将栈顶符号弹出并输出,之后进栈 右括号:将栈顶符号弹出并输出,知道匹配左括号 遍历结束:将栈中所有符号弹出并输出
后缀表达式计算:
对于数字:进栈对于符号: 从栈中弹出右右操作数 从栈中弹出左操作数 根据运算符进行运算 将运算结果入栈遍历结束:栈中唯一数字就是运算结果
有时候代码不重用,重要的是我们的思路,当我们有思路,那么我们剩下的就是把我们向的变为代码就ok了
//linklist.h
#ifndef __LINKLIST_H__#define __LINKLIST_H__typedef struct linklistnode { struct linklistnode *next; int item;}LinkListNode; //数据节点 typedef struct linklist { LinkListNode header; int length;}LinkList; //头节点 LinkList *LinkList_Create();void LinkList_Destroy(LinkList *list);void LinkList_Clear(LinkList *list);int LinkList_Length(LinkList *list);int LinkList_Insert(LinkList *list, LinkListNode *node, int pos);LinkListNode *LinkList_Get(LinkList *list,int pos);LinkListNode *LinkList_Delete(LinkList *list,int pos);#endif //__LINKLIST_H__
//linklist.c
#include <stdlib.h>#include "linklist.h"LinkList *LinkList_Create(){ LinkList *ret = NULL; ret = malloc(sizeof(LinkList)); if(ret!=NULL) { ret->length = 0; ret->header.next = NULL; } return ret;}void LinkList_Destroy(LinkList *list){ free(list);}void LinkList_Clear(LinkList *list){ if(list!=NULL) { list->length =0; list->header.next = NULL; }}int LinkList_Length(LinkList *list){ int ret = -1; if( list!=NULL ) { ret = list->length; } return ret;}int LinkList_Insert(LinkList *list, LinkListNode *node, int pos){ int ret = list!=NULL && node!=NULL && pos>=0; if( ret ) { int i; LinkListNode *cur = (LinkListNode *)list; for(i=0;i<pos && cur->next!=NULL;i++) { cur = cur->next; } node->next = cur->next; cur->next = node; list->length++; } return ret;}LinkListNode *LinkList_Get(LinkList *list,int pos){ LinkListNode *ret = NULL; if( list!=NULL && (0<=pos && pos<list->length) ) { int i; LinkListNode *cur = (LinkListNode *)list; for(i=0; i<pos; i++) cur = cur->next; ret = cur->next; //因为从0开始计数的,要第三个数,那么就是第二个数的next } return ret;}LinkListNode *LinkList_Delete(LinkList *list,int pos){ LinkListNode *ret = NULL; if(list!=NULL && (0<=pos&&pos<list->length) ) { int i; LinkListNode *cur = (LinkListNode *)list; for(i=0; i<pos; i++) cur = cur->next; ret = cur->next; //单项链表是从0开始排的。 cur->next = ret->next; list->length--; } return ret;}
//linkstack.h
#ifndef __LINKSTACK_H__#define __LINKSTACK_H__typedef struct linkstacknode{ struct linkstacknode *node; void *item;}LinkStackNode;typedef void LinkStack;LinkStack *LinkStack_Create();void LinkStack_Destroy(LinkStack *stack);void LinkStack_Clear(LinkStack *stack);int LinkStack_Push(LinkStack *stack,void *item);void *LinkStack_Pop(LinkStack *stack);void *LinkStack_Top(LinkStack *stack);int LinkStack_Size(LinkStack *stack);#endif //__LINKSTACK_H__
//linkstack.c
#include <stdio.h>#include <stdlib.h>#include <string.h>#include "linklist.h"#include "linkstack.h"LinkStack *LinkStack_Create(){ return LinkList_Create();}void LinkStack_Destroy(LinkStack *stack){ LinkStack_Clear(stack); LinkList_Destroy(stack);}void LinkStack_Clear(LinkStack *stack){ while ( LinkStack_Size(stack) > 0 ) LinkStack_Pop(stack);}int LinkStack_Push(LinkStack *stack,void *item){ LinkStackNode *node = malloc(sizeof(LinkStackNode)); int ret = stack!=NULL && item!=NULL && node!=NULL; if( ret ) { memset(node,0x00,sizeof(*node)); //?? node->item = item; ret = LinkList_Insert(stack, (LinkListNode *)node, 0); } if(!ret) { free(node); } return ret;}void *LinkStack_Pop(LinkStack *stack){ LinkStackNode *node = NULL; void *ret = NULL; node = (LinkStackNode *)LinkList_Delete(stack,0); if ( node != NULL) { ret = node->item; free(node); } return ret;}void *LinkStack_Top(LinkStack *stack){ LinkStackNode *node = NULL; void *ret = NULL; node = (LinkStackNode *)LinkList_Get(stack,0); if( node!=NULL) { ret = node->item; } return ret;}int LinkStack_Size(LinkStack *stack){ return LinkList_Length(stack);}
//main.c
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include "linkstack.h"int isNum(char c){ return c>='0' && c<='9';}int isLeft(char c){ return c=='(';}int isRight(char c){ return c==')';}int isOperator(char c){ return c=='+' || c=='-' || c=='*' || c=='/';}int priority(char c){ int ret=0; if( c=='+' || c=='-' ) ret = 1; if( c=='*' || c=='/' ) ret = 2; return ret;}//前缀表达式:void transfrom( const char *exp, char *buf){ int i = 0; int idx = 0; LinkStackNode *stack = LinkStack_Create(); while ( exp[i] != 0 ) { if( isNum(exp[i])) //是数字,直接输出 { //putchar(exp[i]); buf[idx++] = exp[i]; } else if( isLeft(exp[i]) ) //是左(就进栈 { LinkStack_Push(stack, ( void * )(int)exp[i]); } else if ( isOperator(exp[i]) ) //是运算符,就进行比较优先级 { while(priority(exp[i]) <= priority((char)(int)LinkStack_Top(stack))) { //putchar((char)(int)LinkStack_Pop(stack)); //输出栈顶元素 buf[idx++] = ((char)(int)LinkStack_Pop(stack)); } LinkStack_Push(stack, (void *)(int)exp[i]); //在把它进栈 } else if( isRight(exp[i]) ) //是右) 并且栈顶的不是(,就让他一直输出栈顶元素 { while ( !isLeft( (char)(int)LinkStack_Top(stack) )) { //putchar((char)(int)LinkStack_Pop(stack)); buf[idx++] = ((char)(int)LinkStack_Pop(stack)); } LinkStack_Pop(stack); //栈顶是(,则弹出并没有输出 } else { printf("invalid expresstiom!\n"); break; } i++; } while(exp[i]==0 && LinkStack_Size(stack) ) //没有了表达式,并且栈有操作符,就让他直接输入 { //putchar((char)(int)LinkStack_Pop(stack)); buf[idx++] = ((char)(int)LinkStack_Pop(stack)); } //putchar('\n'); buf[idx] = 0; //加了一个‘\0' LinkStack_Destroy(stack);}int value(char c){ return c-'0';}int operation(int left,int right, int op){ int ret = 0; switch (op) { case '+': ret = left + right; break; case '-': ret = left - right; break; case '*': ret = left * right; break; case '/': assert(right); ret = left / right; break; default: printf("error!\n"); exit(1); break; } return ret;}//后缀表达式:int compute(const char *exp){ int i = 0; int res = 0; LinkStack *stack = LinkStack_Create(); while ( exp[i]!= 0 ) { if( isNum(exp[i]) ) //是数字,就进栈 { LinkStack_Push(stack, (void *)value(exp[i])); } else if( isOperator(exp[i]) ) //是操作数,就让栈顶两个数出栈,进行运算 { int r = (int)LinkStack_Pop(stack); int l = (int)LinkStack_Pop(stack); int ret = operation(l,r,exp[i]); LinkStack_Push(stack, (void *)ret); } else { printf("invalid expression!\n"); break; } i++; } if( LinkStack_Size(stack)==1 && exp[i]==0 ) //只有输入一个数的时候,直接让他输出 { res = (int)LinkStack_Pop(stack); } LinkStack_Destroy(stack); return res;}int main( void ){ char buf[1024] = {}; char exp[1024] = {};// transfrom("5+3*2"); while ( 1 ) { printf("输入一个算式表达式:"); fgets(buf, 1024, stdin); //标准输入放入buf中 buf[strlen(buf)-1] = 0; //清掉最后一个换行符 transfrom(buf, exp); //表达式通过buf传过去,在通过exp带回来结果, printf("%s=", buf); printf("%d\n",compute(exp)); }// printf("9-3*2+(5-1)");// printf("%d\n",compute("932*-51-+")); return 0;}
//Makefile
cc :=gccmain : main.o linklist.o linkstack.o gcc $^ -o $@.PHONY : main cleanclean: rm -rf *.o main
3.用栈来实现符号的匹配
和上一个的其他函数都一样,就主函数变化为:
//main.c
#include <stdio.h>#include <stdlib.h>#include "linkstack.h"int isLeft(char c){ return c == '{' || c == '[' || c == '(' || c == '<';}int isRight(char c){ return c == '}' || c == ']' || c == ')' || c == '>';}//匹配int match(char left, char right){ int ret; switch (left) { case '{': ret = right == '}'; break; case '[': ret = right == ']'; break; case '(': ret = right == ')'; break; case '<': ret = right == '>'; break; default: ret = 0; break; } return ret;}/*//扫描int scanner( const char *code ){ int i = 0; // int ret = 0; LinkStackNode *stack = LinkStack_Create(); while ( code[i] !='\0' ) { if( isLeft(code[i]) ) { LinkStack_Push(stack, (void *)(int)code[i]); } if( isRight(code[i])) { char c = (char)(int)LinkStack_Pop(stack); if( !match(c, code[i]) ) { printf("%c no matched\n",code[i]); return -1; // break; } } i++; } if( LinkStack_Size(stack)==0 && code[i]=='\0' ) { printf("success!\n"); } else { printf("invalid!\n"); } LinkStack_Destroy(stack); return 0;// return ret;}*/int scanner( const char *code ){ int i = 0; int ret = 0; LinkStackNode *stack = LinkStack_Create(); while ( code[i] !='\0' ) { if( isLeft(code[i]) ) { LinkStack_Push(stack, (void *)(int)code[i]); } if( isRight(code[i])) { char c = (char)(int)LinkStack_Pop(stack); if( !match(c, code[i]) ) { printf("%c no matched\n",code[i]); ret = -1; break; } } i++; } if( LinkStack_Size(stack)==0 && code[i]=='\0' ) { printf("success!\n"); } else { printf("invalid!\n"); } LinkStack_Destroy(stack); return ret;}int main( void ){ const char *code = "#include <stdlib.h>" "int main( void )" "}"; scanner(code); return 0;}
0 0
- 利用栈实现的经典案例
- 经典利用信号量实现同步的问题
- 接口的经典案例
- 经典的代码案例
- java的经典案例
- MapReduce初级经典案例实现
- MapReduce初级经典案例实现
- 递归经典案例,三角数字的多种实现方式
- 经典案例,二分查找的三种实现方式
- 【经典案例】贪吃蛇 AI 的实现 snake AI
- 最简单的小型商城实现:Serlvet+Jsp经典案例
- 最简单的小型商城实现:Serlvet+Jsp经典案例
- 经典的程序案例1
- 经典的管理经营案例
- 线程间的经典案例
- 正则表达式的经典案例
- 递归经典案例汉诺塔 python实现
- Java实现递归经典案例——三角数字的多种实现方式
- POJ - 3281 Dining (ISAP EK Dinic)
- 自签名证书和私有CA签名的证书的区别 创建自签名证书 创建私有CA 证书类型 证书扩展名
- 面向对象1
- android imeAction 的使用(改变软件键盘回车键的功能与显示文字)
- Oracle远程连接数据库解决方案
- 利用栈实现的经典案例
- Java标识符+常量变量类型+运算符+if和swtich语句-第2天
- 堆排序C语言实现
- Appium国内下载地址
- Overview Screen
- 合唱队形
- gcc编译选项
- SDSoC使用体验
- 小紫书 习题 3-1(UVA 1585) 得分(Score)