栈的应用——就近匹配 (C语言)

就近匹配

在开发的过程中,我们常常遇到成对出现的符号,比如"(" 与")",如果算式中仅仅出现其中一个,则说明算式错误。运用栈一数据结构模型,可以很好进行匹配。
算法思路:
1、从第一个字符开始扫描
2、遇见普通字符时忽略
3、当遇见左括号时压入栈中
4、当遇见右括号时弹出返回栈顶元素,并进行匹配
5、匹配成功,进入下一个字符
6、匹配失败,立即停止并进行报错
7、结束:
成功:所有字符匹配完毕,且栈为空
失败:匹配失败或者所有字符扫描完毕但是栈为非空

代码

"seqStack.h"文件

包含了栈的模型结构与常用接口声名

#pragma  once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define  MAX 1024

//struct SStack
//{
//	void * data[MAX];  //栈的数组
//
//	int m_Size; //栈大小
//};

typedef void * SeqStack;

//初始化栈
SeqStack init_SeqStack();

//入栈
void push_SeqStack(SeqStack stack, void * data);

//出栈
void pop_SeqStack(SeqStack stack);

//返回栈顶
void * top_SeqStack(SeqStack stack);

//返回栈大小
int size_SeqStack(SeqStack stack);

//判断栈是否为空
int isEmpty_SeqStack(SeqStack stack);

//销毁栈
void destroy_SeqStack(SeqStack stack);

"seqStack.c"文件

包含了栈的各自接口的实现,看不懂不了解栈模型的欢迎查看本栏数据结构-线性栈
数据结构 -链表栈

#include "seqStack.h"

struct SStack
{
	void * data[MAX];  //栈的数组

	int m_Size; //栈大小
};

//初始化栈
SeqStack init_SeqStack()
{
	struct SStack * myStack = malloc(sizeof(struct SStack));

	if (myStack == NULL)
	{
		return NULL;
	}

	//初始化数组
	memset(myStack->data, 0, sizeof(void *)* MAX);

	//初始化栈大小
	myStack->m_Size = 0;

	return myStack;
}
//入栈
void push_SeqStack(SeqStack stack, void * data)
{
	//入栈本质  --- 数组尾插
	if (stack == NULL)
	{
		return;
	}
	if (data == NULL)
	{
		return;
	}

	struct SStack * mystack = stack;
	if (mystack->m_Size == MAX)
	{
		return;
	}

	mystack->data[mystack->m_Size] = data;

	mystack->m_Size++;
}
//出栈
void pop_SeqStack(SeqStack stack)
{
	//出栈本质  --- 数组尾删
	if (stack == NULL)
	{
		return;
	}

	struct SStack * mystack = stack;

	if (mystack->m_Size == 0)
	{
		return;
	}

	mystack->data[mystack->m_Size - 1] = NULL;

	mystack->m_Size--;

}
//返回栈顶
void * top_SeqStack(SeqStack stack)
{
	if (stack == NULL)
	{
		return NULL;
	}

	struct SStack * mystack = stack;

	if (mystack->m_Size == 0)
	{
		return NULL;
	}
	return mystack->data[mystack->m_Size - 1];
}
//返回栈大小
int size_SeqStack(SeqStack stack)
{
	if (stack == NULL)
	{
		return -1;
	}

	struct SStack * mystack = stack;

	return mystack->m_Size;

}
//判断栈是否为空
int isEmpty_SeqStack(SeqStack stack)
{
	if (stack == NULL)
	{
		return -1;//返回-1代表真  空栈
	}

	struct SStack * mystack = stack;

	if (mystack->m_Size == 0)
	{
		return 1;
	}

	return 0; //返回0 代表 不是空栈

}
//销毁栈
void destroy_SeqStack(SeqStack stack)
{
	if (stack == NULL)
	{
		return;
	}

	free(stack);
	stack = NULL;
}

具体实现代码

//
// Created by szw on 2021/9/23.
//

#include "Proximity matching of stacks.h"
#include <stdio.h>
#include "stdlib.h"
#include "string.h"
#include "seqStack.h"

//算法思路
/*
 * 栈的应用案例
就近匹配
 1、从第一个字符开始扫描
 2、遇见普通字符时忽略
 3、当遇见左括号时压入栈中
 4、当遇见右括号时弹出返回栈顶元素,并进行匹配
 5、匹配成功,进入下一个字符
 6、匹配失败,立即停止并进行报错
 7、结束:
 成功:所有字符匹配完毕,且栈为空
 失败:匹配失败或者所有字符扫描完毕但是栈为非空
 */
//判断左括号
int isLeft(char * p)
{
    return '('== *p;
}
//判断右括号
int isRight(char * p)
{
    return ')' ==* p;
}
//打印错误函数
void printError(char *str ,char *Msg ,char *pos)
{
    printf("错误信息:%s\n",Msg);
    printf("%s\n",str);
    int mis_num = pos - str;//计算出错位置
    for (int i = 0; i <mis_num ; ++i) {
        printf(" ");
    }
    printf("^\n");
}
void test01(){
//    char *str = "5+5*(6)+9/3*1)-(1+3(";
    char *str =  "5+5*(6)+9/3*1-(1+3(";
    //定义一个指针指向字符串的首地址
    char * p =str;
    //初始化栈
    SeqStack  myStack = init_SeqStack();
    //开始循环扫描操作
    while (*p != '\0')
    {
        //判断如果是左括号,则进行入栈
        if (isLeft(p)){
            push_SeqStack(myStack,p);
        }
        //如果是右括号
        if (isRight(p))
        {
            //情况1 如果是空栈报错
            //情况2 不为空栈,出栈
            if(size_SeqStack(myStack)>0)
            {
                //情况2
                pop_SeqStack(myStack);
            }
            else
            {
                //情况1 立即停止报错
                printError(str,"右括号无法匹配左括号",p);
                break;
            }

        }
        p++;
    }
    //左括号没有匹配到右括号的情况
    //如果没有匹配到,栈一定不为空
    while (size_SeqStack(myStack)>0)
    {
        printError(str,"左括号没有匹配到右括号", top_SeqStack(myStack));
        pop_SeqStack(myStack);
    }
    //销毁栈
    destroy_SeqStack(myStack);

}


int main() {
    test01();
    return 0;
}

运行图例

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

toptap8_nn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值