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

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;
}
相关推荐
熬夜学编程的小王1 小时前
【C++篇】深度解析 C++ List 容器:底层设计与实现揭秘
开发语言·数据结构·c++·stl·list
阿史大杯茶1 小时前
AtCoder Beginner Contest 381(ABCDEF 题)视频讲解
数据结构·c++·算法
Chris _data1 小时前
二叉树oj题解析
java·数据结构
Lenyiin3 小时前
02.06、回文链表
数据结构·leetcode·链表
爪哇学长3 小时前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
爱摸鱼的孔乙己3 小时前
【数据结构】链表(leetcode)
c语言·数据结构·c++·链表·csdn
烦躁的大鼻嘎3 小时前
模拟算法实例讲解:从理论到实践的编程之旅
数据结构·c++·算法·leetcode
C++忠实粉丝3 小时前
计算机网络socket编程(4)_TCP socket API 详解
网络·数据结构·c++·网络协议·tcp/ip·计算机网络·算法
daiyang123...5 小时前
测试岗位应该学什么
数据结构
kitesxian5 小时前
Leetcode448. 找到所有数组中消失的数字(HOT100)+Leetcode139. 单词拆分(HOT100)
数据结构·算法·leetcode