【C/C++】栈的应用—分隔符匹配算法

一、算法描述

首先需要提前知道的是,常见分隔符有{ }/* */,它们的使用是循环嵌套的,如果嵌套多层,那么左分隔符将会一直压栈,直到遇到第一个右分隔符。

如果分隔符是匹配的,那么栈顶的左分隔符,就是与之匹配的。例如{[()]},左分隔符入栈,栈顶是’(’,那么遇到的第一个右分隔符就是’)’,如果不是就匹配失败。

算法描述:

(1)从左到右读取字符,每次读取一个字符,若判定为是左分割符,则将它压入栈;

(2)当读取到一个右分割符时,则弹出栈顶 的左分隔符,并判定它是否和此右分隔符匹配,若它们不匹配,则匹配失败,函数返回false;


(3)若栈一直存在没有被弹出的左分隔符,即左分隔符多余,则匹配失败,函数返回false;


(4)若所有的字符都匹配,那么栈顶一直弹出,直到栈为空。等到读入结束后,栈就为空,则表示匹配成功,函数返回true

即只有当栈为空才返回true,其他情况均不匹配,返回false

二、 实现代码

#include <iostream>
#include <stack>
using namespace std;

bool delimiterMatching(char* file);//定义判断分隔符是否匹配的函数

int main()
{
	char fileName[50];//定义字符数组

	cout << "Enter a statement (Ex. s=t[5]+x/(m*(n+y));   : ";
	cin >> fileName;

	if (delimiterMatching(fileName))//将fileName传入delimiterMatching函数
		cout << endl << "Matching success." << endl;
	else
		cout << endl << "Matching failure." << endl;
}

bool delimiterMatching(char* file)
{
	stack<char> var;//定义一个栈
	int counter = 0;//计数
	char ch, temp, popd;//ch储存字符的变量,temp暂时储存字符的变量,popd暂时储存栈顶部元素

	do {
		ch = file[counter];//file的第一个字符
		if (ch == '(' || ch == '[' || ch == '{')//如果该字符为左分隔符
		{
			var.push(ch);//将ch压入栈
		}
		else if (ch == '/')//如果该字符为左分隔符
		{
			temp = file[counter + 1];//获取‘/’的下一个字符
			if (temp == '*')//下一个字符为‘*’,就是注释,需要寻找匹配
			{
				var.push(ch);//将‘/’压入栈
				counter++;
			}
			else//如果是其他的字符,不压栈
			{
				counter++;//下一个字符
				continue;//回到循环开始
			}
		}
		else if (ch == ')' || ch == ']' || ch == '}') //如果该字符为右分隔符
		{
			popd = var.top();//返回栈顶部元素
			var.pop();//栈顶部元素出栈,栈中元素-1

			if ((ch == ')' && popd != '(') || (ch == ']' && popd != '[') || (ch == '}' && popd != '{'))//如果ch和弹出的分隔符不匹配,就报告错误
				return false;
		}
		else if (ch == '*')//如果该字符为右分隔符
		{
			temp = file[counter + 1];//获取下一个字符
			popd = var.top();//返回栈顶部的元素
			var.pop();//栈顶部元素出栈

			if (temp == '/')//如果下一个字符为‘/’,则为注释的后半部分,需要寻找匹配
			{
				if (popd == '/')//如果匹配成功
				{
					counter++;//下一个字符
					continue;//回到循环开始
				}
				else//匹配不成功,报告错误
				{
					return false;
					break;
				}
			}
			else//不是则重新循环 - 为*运算符
			{
				var.push(popd);//归还出栈的顶部元素
				counter++;//下一个字符
				continue;//回到循环开始
			}
		}
		counter++;//字符不符合以上要求跳过,进行下一个字符的判断
	} while (ch != '\0');//当遇到空字符,终止循环

	if (var.empty())//如果栈为空,则正确匹配,返回true
		return true;
	else
		return false;
}

需要注意的是:对于有多种用处的字符,需要对其进行额外的判断,例如:*和/,既可以是算术运算符,也可以是注释里的符号。因此上面的判断函数中,就判断其是不是注释的分隔符,如果不是就跳过,因为运算符不是分隔符。

三、运行效果

在这里插入图片描述
在这里插入图片描述如有不足之处,还望指正 1


  1. 如果对您有帮助可以点个赞或关注,将会是我最大的动力 ↩︎

发布了7 篇原创文章 · 获赞 10 · 访问量 833

猜你喜欢

转载自blog.csdn.net/CoutCodes/article/details/104978731