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 :=gcc
main : main.o linklist.o linkstack.o
gcc $^ -o $@
.PHONY : main clean
clean:
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 :=gcc
main : main.o linklist.o linkstack.o
gcc $^ -o $@
.PHONY : main clean
clean:
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;
}