数据结构----栈的应用

1 顺序栈的应用

检测代码完整性

内容:

使用顺序栈实现检测代码是否完整,打开一个.c文件,检测里面的内容中()、{ }、[ ]是否配对成功,不缺少符号。

原理:

打开文件,遍历每个字符,检测到(、{、[、就放入顺序栈中,遇到 )、}、]、就将相对应的符号取出。记录行号等其他信息

代码:

seqstack.h和sequstack.c代码均为上一篇文章中的源代码。

  1. do_check函数用于检查一个字符串中的括号是否匹配,并在遇到不匹配的情况下输出错误信息。
  2. main函数打开指定的C源文件,并逐行读取其中的内容,对每一行调用do_check函数进行括号匹配检查。
  3. 如果检查过程中发现了不匹配的括号,则输出错误信息;如果全部检查通过,则输出"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代码均为上一篇文章中的源代码。

  1. get_num函数用于从字符中获取数字,并将其转换为整数。
  2. get_priority函数用于获取运算符的优先级,便于后续的运算符比较。
  3. get_result函数用于根据运算符计算两个操作数的结果。
  4. 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;
}
相关推荐
丶Darling.1 小时前
代码随想录 | Day26 | 二叉树:二叉搜索树中的插入操作&&删除二叉搜索树中的节点&&修剪二叉搜索树
开发语言·数据结构·c++·笔记·学习·算法
no_play_no_games2 小时前
「3.3」虫洞 Wormholes
数据结构·c++·算法·图论
PYSpring3 小时前
数据结构-LRU缓存(C语言实现)
c语言·数据结构·缓存
Mr Aokey3 小时前
双向无头非循环链表的简单实现及介绍
数据结构
狐小粟同学4 小时前
链表面试编程题
数据结构·链表·面试
CyberMuse5 小时前
数值计算的程序设计问题举例
数据结构
陈奕迅本讯5 小时前
数据结构-链表笔记
数据结构·笔记·链表
江奖蒋犟5 小时前
【初阶数据结构】排序——归并排序
c语言·数据结构·算法
cdut_suye5 小时前
STL之list篇(下)(从底层分析实现list容器,逐步剥开list的外表)
开发语言·数据结构·c++·学习·算法·stl·list
Felix Du6 小时前
数据结构与算法(七)静态链表
c语言·数据结构·学习·算法·链表