您的位置:首页 > 理论基础 > 数据结构算法

C语言数据结构之利用栈进行括号匹配的检验

2018-03-02 20:55 471 查看
括号匹配的检验:
    eg: [([][][)]]    不匹配
        [([][])] 匹配

思路:  

0x0.首先建立两个栈,并对其初始化     

0x1.对表达式进行遍历,将相邻两个不能匹配的入栈到栈A,然后检测栈空间A是否为偶数,如果是表明有存在的可能,如果不是则提示不匹配。
0x2.检测栈空间A是否为偶数,如果是表明有存在的可能,如果不是则提示不匹配[b],[b]遍历栈A,将不匹配的入栈到栈B,如果匹配则判断是否是最后两个元素,如果是表明匹配[/b][/b]
0x3.判断出栈前的A和栈B长度是否相等,如果相等表明不匹配。
0x4.栈A和栈B互换,重复步骤0x2,直到都为空.

运行截图:



代码:

Stack.h
#ifndef _STACK_H_
#define _STACK_H_

#include <stdbool.h>
#define STACK_INIT_SIZE 100 //栈控件初始化大小
#define STACK_INCREMENT 10 //栈控件增量

typedef struct{
void * base;//栈底
void * top;//栈顶
int stackSize;//当前已经分配的存储空间
int elementLength;
}SqStack;

typedef enum{
FAILED,SUCCESS
}Status;

Status initStack(SqStack * pStack,int elength);

void destroyStack(SqStack * pStack);
void clearStack(SqStack * pStack);//将栈置空
bool stackIsEmpty(SqStack * pStack);
int stackLength(const SqStack * pStack);
void * getTop(SqStack * pStack);
void push(SqStack * pStack,void *data);//压栈
void pop(SqStack * pStack,void *data);//出栈,若不空删除栈顶元素并将其值返回

void * get(SqStack * pStack,int i);//获取栈的第i个位置的元素

/**
* 输出栈中每个元素,如果direction为正则从头到尾输出,反之从尾到头输出.
* @param pStack
* @param pfun
* @param direction
*/
void stackTraverse(SqStack * pStack,void(*pfun)(void *),int direction);

#endif

Stack.c
#include <malloc.h>
#include <memory.h>
#include <assert.h>
#include "Stack.h"

Status initStack(SqStack * pStack,int elength)
{

pStack->base = malloc((size_t) (elength * STACK_INIT_SIZE));
if(!pStack->base)//如果分配内存失败
return FAILED;

pStack->elementLength = elength;
pStack->top = pStack->base;
pStack->stackSize = STACK_INIT_SIZE;

return SUCCESS;
}

void destroyStack(SqStack * pStack)
{
if(pStack)
{
free(pStack->base);
pStack->base = NULL;
pStack->top = NULL;
pStack->stackSize = 0;
}

}

void clearStack(SqStack * pStack)//将栈置空
{
if(pStack)
pStack->top = pStack->base;
}

bool stackIsEmpty(SqStack * pStack)
{
if(pStack)
{
if(pStack->top == pStack->base)
return true;
else
return false;
}

return false;
}

/**
* 返回栈当前长度
* 用栈顶减去栈底除以单个元素大小即可.
* @param pStack
* @return
*/
int stackLength(const SqStack * pStack)
{
return (int) (pStack->top - pStack->base)/pStack->elementLength;
}

void * getTop(SqStack * pStack)
{
if(pStack->top == pStack->base)
return NULL;
else
return pStack->top;
}

void push(SqStack * pStack,void *data)//压栈
{

if((pStack->top - pStack->base)/pStack->elementLength >= pStack->stackSize)
{
pStack->base =
realloc(pStack->base,
(size_t) ((pStack->stackSize + STACK_INCREMENT)*pStack->elementLength));

assert(pStack->base != NULL);
pStack->top = pStack->base+pStack->stackSize*pStack->elementLength;
pStack->stackSize += STACK_INCREMENT;
}
memcpy(pStack->top, data, (size_t) pStack->elementLength);

pStack->top = pStack->top+pStack->elementLength;
}

void pop(SqStack * pStack,void *data)//出栈,若不空删除栈顶元素并将其值返回
{
if(pStack->top != pStack->base)
{
pStack->top -= pStack->elementLength;

if(data)
memcpy(data,pStack->top,(size_t)pStack->elementLength);
}
}

void * get(SqStack * pStack,int i)//获取栈的第i个位置的元素
{
void * pn = NULL;

if(stackLength(pStack) != 0)
pn = &pStack->base[i];

return pn;
}

/**
*
* @param pStack
* @param pfun
* @param direction 遍历方向
* @param isHex 是否是16进制
*/
void stackTraverse(SqStack * pStack,void(*pfun)(void *),int direction)
{
void * pd = NULL;
if(direction > 0)
{
pd = pStack->base;

while(pd < pStack->top)
{
pfun(pd);
pd += pStack->elementLength;
}
}else{
pd = pStack->top;

while(pd > pStack->base)
{
pd -= pStack->elementLength;
pfun(pd);
}
}

}main5.c
#include <stdio.h>
#include <stdlib.h>
#include "Stack.h"

bool signEqual(char * c1,char * c2);

/**
* 括号匹配检验
* @return
*/

int main(void) {
SqStack stack,stack2,staTemp;
initStack(&stack, sizeof(char));
initStack(&stack2, sizeof(char));
printf("请输入需要检测的字符串,以#结尾:");
char c, temp;

scanf("%c", &c);
//[([][][)]]
//[][][
//检测括号是否匹配.

while (c != '#')
{
if(c == '(' || c == '[' || c==')' || c==']')
{
scanf("%c",&temp);

if(signEqual(&c,&temp))//如果匹配
{
scanf("%c",&c);
}else{
push(&stack,&c);
c = temp;
}
}else if(c !='#'){
printf("表达式中只允许包含[]()两种括号!\n");
exit(1);
}
}

int len,len2;
while(!(stackIsEmpty(&stack) && stackIsEmpty(&stack2)))
{

len = stackLength(&stack);

if(len%2 == 0)//为偶数対表明存在正确匹配的可能
{
pop(&stack,&c);
do
{
pop(&stack,&temp);
if(signEqual(&c,&temp))
{
if(len == 2)
{
printf("表达式括号匹配!\n");
exit(1);
}
pop(&stack,&c);
}else{//不匹配
if(len == 2)
{
printf("表达式括号不匹配!\n");
exit(1);
}
push(&stack2,&c);
c = temp;
}
}while(!stackIsEmpty(&stack));//如果栈不空

push(&stack2,&c);//将剩下的一个入栈
}else{
printf("表达式括号不匹配!\n");
exit(1);
}

len2 = stackLength(&stack2);
if(len == len2){
printf("表达式括号不匹配!\n");
exit(1);
}

staTemp = stack;//交换顺序
stack = stack2;
stack2 = staTemp;
}

return 0;
}

/**
* 判断符号1和符号二是否匹配
* @param c1
* @param c2
* @return
*/
bool signEqual(char * c1,char * c2)
{
if(*c1 == '[')
{
if(*c2 == ']')
return true;
else
return false;
}else if(*c1 == '(')
{
if(*c2 == ')')
return true;
else
return false;
}else if(*c1 == ']')
{
if(*c2 == '[')
return true;
else
return false;
}else if(*c1 == ')')
{
if(*c2 == '(')
return true;
else
return false;
}
return false;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: