1 顺序栈的应用
检测代码完整性
内容:
使用顺序栈实现检测代码是否完整,打开一个.c文件,检测里面的内容中()、{ }、[ ]是否配对成功,不缺少符号。
原理:
打开文件,遍历每个字符,检测到(、{、[、就放入顺序栈中,遇到 )、}、]、就将相对应的符号取出。记录行号等其他信息
代码:
seqstack.h和sequstack.c代码均为上一篇文章中的源代码。
do_check
函数用于检查一个字符串中的括号是否匹配,并在遇到不匹配的情况下输出错误信息。main
函数打开指定的C源文件,并逐行读取其中的内容,对每一行调用do_check
函数进行括号匹配检查。- 如果检查过程中发现了不匹配的括号,则输出错误信息;如果全部检查通过,则输出"ok!"。
cpp
#include "seqstack.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int do_check(char *buf,SeqStack* ss,int row)
{
DATATYPE data;
int col =1;
DATATYPE* tmp=NULL;
while(*buf)
{
bzero(&data,sizeof(data));
switch(*buf)
{
case '(':
data.sym = *buf;
data.row = row;
data.col = col;
PushSeqStack(ss,&data);
break;
case '[':
data.sym = *buf;
data.row = row;
data.col = col;
PushSeqStack(ss,&data);
break;
case '{':
data.sym = *buf;
data.row = row;
data.col = col;
PushSeqStack(ss,&data);
break;
case ')':
tmp= GetTopSeqStack(ss);
if(NULL == tmp)
{
printf("buf sym:%c row:%d col:%d\n",*buf,row,col);
return 1;
}
if('('==tmp->sym )
{
PopSeqStack(ss);
}
else
{
printf("1.top error sym:%c row:%d col:%d or 2 buf sym:%c row:%d col%d\n",
tmp->sym ,tmp->row ,tmp->col,*buf,row,col );
return 1;
}
break;
case ']':
tmp= GetTopSeqStack(ss);
if(NULL == tmp)
{
printf("buf sym:%c row:%d col:%d\n",*buf,row,col);
return 1;
}
if('['==tmp->sym )
{
PopSeqStack(ss);
}
else
{
printf("1.top error sym:%c row:%d col:%d or 2 buf sym:%c row:%d col%d\n",
tmp->sym ,tmp->row ,tmp->col,*buf,row,col );
return 1;
}
break;
case '}':
tmp= GetTopSeqStack(ss);
if(NULL == tmp)
{
printf("buf sym:%c row:%d col:%d\n",*buf,row,col);
return 1;
}
if('{'==tmp->sym )
{
PopSeqStack(ss);
}
else
{
printf("1.top error sym:%c row:%d col:%d or 2 buf sym:%c row:%d col%d\n",
tmp->sym ,tmp->row ,tmp->col,*buf,row,col );
return 1;
}
break;
}
buf++;
col++;
}
return 0;
}
int main(int argc, char *argv[])
{
SeqStack* ss = CreateSeqStack(50);
FILE* fp = fopen("/home/linux/1.c","r");
if(NULL == fp)
{
perror("fopen");
exit(1);
}
int flag = 0;
int row =1;
while(1)
{
char buf[512]={0};
if(fgets(buf,sizeof(buf),fp))
{
int ret = do_check(buf,ss,row);
if(ret!= 0 )
{
flag = 1;
break;
}
}
else
{
break;
}
row++;
}
if(1 == flag)
{
return 0;
}
else
{
if(IsEmptySeqStack(ss))
{
printf("ok!");
}
else
{
DATATYPE* tmp = GetTopSeqStack(ss);
printf("%c row:%d col:%d\n",tmp->sym ,tmp->row ,tmp->col);
}
}
return 0;
}
2 链栈的应用
四则运算表达式求值
内容:
使用链栈的方式实现四则运算表达式,并非直接使用系统底层计算逻辑,自己编写一个函数实现四则运算。
原理:
从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于栈顶符号(乘除优先加减)则栈顶元素依次出栈并输出,并将当前符号进栈,一直到最终输出后缀表达式为止。
代码:
linkstack.h和linkstack.c代码均为上一篇文章中的源代码。
get_num
函数用于从字符中获取数字,并将其转换为整数。get_priority
函数用于获取运算符的优先级,便于后续的运算符比较。get_result
函数用于根据运算符计算两个操作数的结果。main
函数中使用了两个链栈,一个存储数字,另一个存储运算符。通过遍历输入的表达式,按照运算符的优先级进行运算,并将中间结果存储在数字栈中,直到表达式全部处理完毕,最终输出结果。
cpp
#include "linkstack.h"
#include <stdio.h>
#include <string.h>
//30*2+5
//
int num =0;
void get_num(char c)
{
num = num*10 +c-'0' ;
}
int get_pority(char c)
{
switch(c)
{
case '+':
return 1;
case '-':
return 2;
case '*':
return 3;
case '/':
return 4;
}
return -1;
}
int get_result(int num1,int num2,char op)
{
switch(op)
{
case '+':
return num1+num2;
case '-':
return num1-num2;
case '*':
return num1*num2;
case '/':
return num1/num2;
}
return 0;
}
int main(int argc, char *argv[])
{
char buf[]="30*2+5";
LinkStackList* ls_num = CreateLinkStack();
LinkStackList* ls_sym = CreateLinkStack();
char* tmp = buf;
DATATYPE data;
int flag = 0 ;
while(*tmp)
{
bzero(&data,sizeof(data));
if(*tmp>='0' && *tmp<='9')
{
get_num(*tmp);
tmp++;
continue;
}
if(0 == flag)
{
data.num = num;
PushLinkStack(ls_num,&data);
num=0;
}
DATATYPE* top =GetTopLinkStack(ls_sym);
if(IsEmtpyLinkStack(ls_sym) || get_pority(top->sym) < get_pority(*tmp) )
{
bzero(&data,sizeof(data));
data.sym = *tmp;
PushLinkStack(ls_sym,&data);
flag = 0 ;
}
else
{
DATATYPE* top_num = GetTopLinkStack(ls_num);
int num2 = top_num->num;
PopLinkStack(ls_num);
top_num = GetTopLinkStack(ls_num);
int num1 =top_num->num;
PopLinkStack(ls_num);
DATATYPE* top_sym = GetTopLinkStack(ls_sym);
char op=top_sym ->sym;
int result = get_result(num1,num2,op);
PopLinkStack(ls_sym);
bzero(&data,sizeof(data));
data.num = result;
PushLinkStack(ls_num,&data);
flag = 1;
continue;
}
tmp++;
}
bzero(&data,sizeof(data));
data.num = num;
PushLinkStack(ls_num ,&data);
while(!IsEmtpyLinkStack(ls_sym))
{
DATATYPE* top_num = GetTopLinkStack(ls_num);
int num2 = top_num->num;
PopLinkStack(ls_num);
top_num = GetTopLinkStack(ls_num);
int num1 =top_num->num;
PopLinkStack(ls_num);
DATATYPE* top_sym = GetTopLinkStack(ls_sym);
char op=top_sym ->sym;
int result = get_result(num1,num2,op);
PopLinkStack(ls_sym);
bzero(&data,sizeof(data));
data.num = result;
PushLinkStack(ls_num,&data);
}
DATATYPE* top_result = GetTopLinkStack(ls_num);
printf("result is %d\n",top_result->num);
return 0;
}