栈的应用 - 就近匹配

链式存储栈的API详情參看我的博文:栈的链式存储 - API实现

就近匹配

差点儿全部的编译器都具有检測括号是否匹配的能力

怎样实现编译器中的符号成对检測?

#include <stdio.h> int main() { int a[4][4]; int (*p)[4]; p = a[0]; return 0;

算法思路

从第一个字符開始扫描

当遇见普通字符时忽略。

当遇见左符号时压入栈中

当遇见右符号时从栈中弹出栈顶符号。并进行匹配

匹配成功:继续读入下一个字符

匹配失败:马上停止。并报错

结束:

成功: 全部字符扫描完成。且栈为空

失败:匹配失败或全部字符扫描完成但栈非空

当须要检測成对出现但又互不相邻的事物时

能够使用栈“后进先出”的特性

栈很适合于须要“就近匹配”的场合

主要代码:

// scanner.h
// 栈的案例:就近匹配

#include "stdio.h"
#include "stdlib.h"
#include "linkstack.h"

int isLeft(char c)
{
	int ret = 0;

	switch (c) {
	case '<':
	case '(':
	case '[':
	case '{':
		ret = 1;
		break;
	default:
		break;
	}

	return ret;
}

int isRight(char c)
{

	int ret = 0;

	switch (c) {
	case '>':
	case ')':
	case ']':
	case '}':
		ret = 1;
		break;
	default:
		break;
	}

	return ret;
}

int match(char left, char right)
{
	int ret = 0;

	switch (left) {
	case '<':
		ret = (right == '>');
		break;
	case '(':
		ret = (right == ')');
		break;
	case '[':
		ret = (right == ']');
		break;
	case '{':
		ret = (right == '}');
		break;
	case '\'':
		ret = (right == '\'');
		break;
	case '\"':
		ret = (right == '\"');
		break;
	default:
		ret = 0;
		break;
	}

	return ret;
}

void scanner(const char* code)
{
	LinkStack *stack = LinkStack_Create();
	int i = 0;

	while (code[i] != '\0') {
		if (isLeft(code[i])) {
			LinkStack_Push(stack, (void *)&code[i]);
		}

		if (isRight(code[i])) {
			char *c = (char *)LinkStack_Pop(stack);

			if (c == NULL || !match(*c, code[i])) {
				printf("%c does not match!\n", code[i]);
				break;
			}
		}

		++i;
	}

	if (LinkStack_Size(stack) == 0 && code[i] == '\0') {
		printf("Success!\n");
	}
	else {
		printf("Fail!\n");
	}

	LinkStack_Destroy(stack);
}

void playScanner()
{
	const char* code = "#include <stdio.h> int main() { int a[4][4]; int (*p)[4]; p = a[0]; return 0; ";

	scanner(code);

	return;
}

代码详情參看:Github

时间: 2024-12-28 11:55:52

栈的应用 - 就近匹配的相关文章

数据结构 栈的应用一(就近匹配)

//栈的应用--就近匹配 #include<stdio.h> #include<stdlib.h> #include<string.h> #include"LinkStack.h"//引用链表栈动态库 /* 思路:遍历每个字符,遇到左符号压栈,遇到右符号出栈,比较出栈的符号是否和右符号匹配,遇到普通符号不管 */ //符号处理 int ProtectSymbol(char ch, LinkStack *stack){ char tempc = 0,

栈2--括号的匹配

栈2--括号的匹配 一.心得 二.题目及分析 有(和),如果匹配输出1,如果不匹配输出0. 三.代码及结果 1 #include <iostream> 2 using namespace std; 3 4 bool judge(char c[256]){ 5 int top=0; 6 int i=0; 7 while(c[i]!='@'){ 8 if(c[i]=='(') top++; 9 if(c[i]==')'){ 10 if(top>0) top--; 11 else return

C数据结构-栈和队列,括号匹配举例

1.栈和队列是两种特殊的线性表 运算操作被限定只能在表的一端或两端插入,删除元素,故也称它们为限定的线性表结构 2.栈的基本运算 1).Stackinit(&s) 构造一个空栈 2).Stackempty(s) 判断s是否为空栈,当s为空栈时,函数返回值1 否则 0 3).Push(&s,x)  在栈s 的顶部插入元素x,简称将x入 栈 4).Pop(&s,&x) 在栈s 中删除顶元并将其值保存在x单元中返回,简称将x出栈 5)Gettop(s,&x)  读s栈中的

[栈和队列]括号匹配

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #define INIT_STACK_SIZE 100 5 typedef struct 6 { 7 char * chOperator; 8 int dwtop; 9 }OPND; 10 11 void InitStack(OPND *); 12 char Pop(OPND *); 13 void Push(OPND *,char );

栈的应用—分隔符匹配

例二.分隔符匹配问题 1.问题描述 编译器在编译一段代码时,首先进行的就是分隔符的匹配,常见的分隔符有{   } [   ]  (   )/*  */ 2.思路 首先要知道的一件事就是:分隔符运行嵌套,而且,读入的顺序和处理的顺序相反,很显然是用栈. 算法描述如下: 从左到右扫描java语句,从语句中不断的读取字符,每次读取一个字符,若发现它是左分割符,则将它压入栈: 当从输入中读到一个右分割符时,则弹出栈顶 的左分隔符,并且查看它是否和右分隔符匹配,若它们不匹配,则匹配失败,程序报错: 若栈顶

leetcode题解:Valid Parentheses(栈的应用-括号匹配)

题目: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]&

【数据结构】用栈检测括号是否匹配

//[数据结构]用栈检测括号是否匹配 //头文件 栈 #ifndef _STACK_ #define _STACK_ #include <iostream> #include <string.h> using namespace std; template <class Type> class Stack { public: Stack(size_t sz = INIT_SIZE) { capacity = sz > INIT_SIZE ? sz : INIT_S

数据结构实验之栈四:括号匹配(栈)

数据结构实验之栈四:括号匹配 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 给你一串字符,不超过50个字符,可能包括括号.数字.字母.标点符号.空格,你的任务是检查这一串字符中的( ) ,[ ],{ }是否匹配. 输入 输入数据有多组,处理到文件结束. 输出 如果匹配就输出"yes",不匹配输出"no" 示例输入 sin(20+10) {[}] 示例输出 yes no 提示 来源 ma6174

栈应用之括号匹配

栈的使用之括号匹配 Char s[n]是一个字符串数组.Stack是一栈,i是元素对应的下表.设一个char flag[n]数组,用来标记是否匹配,数组中数值是‘l’(左不匹配,即没有找到右括号),‘r’(右不匹配),‘o’匹配成功. 算法描述: (1)遍历该字符串数组. While(遍历){ if遇到‘(’,do stack.push(i)(i 是‘(’对应的数组下表),flag[i]=’o’(不一定就是匹配成功,以后遍历完如果stack还有元素,说明没有左匹配,要改成‘l’:如果没有,则就是