顺序栈实例应用【分隔符匹配问题】

分隔符有哪些?

分隔符的匹配是任意编译器的一部分, 若分隔符不匹配,则程序不可能正确。Java程序中有以下分隔符: “(”和“)”、“{”和"}"、"[“和 “]” 及注释”/"和 "/"

怎么算匹配成功?

首先知道栈是先进后出的特点 学会运用栈的入栈和出栈的操作,进行对分隔符的处理。

例如:
假设在表达式中
([]())或[([ ]/[ ]/)]
等为正确的格式,

[( ])或(())])或([( )]
均为不正确的格式。

由上面的表达式我们可以了解到分隔符匹配算法的归纳如下:

在java程序中,依次从左到右依次读取字符,每读取一个字符,若发现它是左分隔符,则将它压入栈中;当从输入中读取到的是右分隔符时,弹出栈顶的左分隔符,查看它是否与这个右分隔符匹配,不匹配,则程序报错!匹配失败;若所有的字符读入结束后,栈为空(即所有的左分隔符与右分隔符匹配),则匹配成功!

匹配失败有以下这三种情况:

  • 1.和栈顶的左分隔符不相匹配;
  • 2.栈中并没有左分隔符等在那里;
  • 3.栈中还有左分隔符没有等到和它相匹配的右括弧。
    例题

第一个括号序列:首先左分隔符1、2进栈,出现右分隔符3,把栈顶元素2取出与右分隔符比较,发现不匹配。程序报错! 匹配不成功!

第二个括号序列:1、2进栈,出现右分隔符,取出栈顶2与栈顶分隔符3比较,匹配成功;栈中还有1这个左分隔符,当再出现右分隔符,再取出栈顶分隔符1与4比较,匹配成功;当再出现右分隔符5、6,但栈为空,没有了左分隔符与它比较,到来的是“不速之客”,所以程序报错!匹配不成功!

第三个括号序列:对应上述匹配不成功的第三种情况(1秃头,没人要了)。

分隔符匹配算法实现

算法实现思想:

  • 1)凡出现左括弧,则进栈;
  • 2)凡出现右括弧,首先检查栈是否空 , 若栈空,则表明该“右括弧”多余, 若不为空,取出栈顶左括弧,与右括弧比较
    若相匹配,则“左括弧出栈” ,
    否则表明不匹配。
  • 3)表达式检验结束时, 若栈空,则表明表达式中匹配正确, 否则表明“左括弧”有余。

算法实现:

import java.util.Scanner;

import com.landuodexiaohei.sy2_2.SqIStack;

/**
 * 分隔符匹配问题,注意导入栈包
 * @懒惰的小黑
 *
 */
public class Example1_1 {
	//记录“做分隔符”、“右分隔符”和其它字符的常量,只是方便返回值。
	public final int LEFT = 0;
	public final int RIGHT = 1;
	public final int OTHER = 2;
	
	//记录左右分隔符和其它字符
	public int verfyFlag(String str) {
		if("(".equals(str)||"[".equals(str)||"{".equals(str)||"/*".equals(str)) {
			return LEFT;
		}else if(")".equals(str)||"]".equals(str)||"}".equals(str)||"*/".equals(str)) {
			return RIGHT;
		}else {
			return OTHER;
		}
	}
	
	//检验左右分隔符是否匹配
	public boolean matchs(String str1,String str2) {
		if(("(".equals(str1)&&")".equals(str2))||("[".equals(str1)&&"]".equals(str2))
				||("{".equals(str1)&&"}".equals(str2))||
				("/*".equals(str1)&&"*/".equals(str2))) {
			return true;
		}else {
			return false;
		}
	}
	
	//检验串中的分隔符是否匹配
	public boolean isLegal(String str) throws Exception {
		if(!"".equals(str)&&str!=null) {		//str不等于空白串或空
			SqIStack s = new SqIStack(100);		//创建容量内存为100的空栈
			int length = str.length();
			for(int i=0;i<length;i++) {
				char c = str.charAt(i);			//转化为字符
				String t = String.valueOf(c);	//把每一个字符转换为字符串
				if(i!=length) {
					if(('/'==c&&'*'==str.charAt(i+1))||('*'==c&&'/'==str.charAt(i+1))) {
						t = t.concat(String.valueOf(str.charAt(i+1)));	//与前面的字符连接
						++i;					//跳过一个字符
					}
				}
				if(LEFT == verfyFlag(t)) {
					s.push(t);
				}else if(RIGHT == verfyFlag(t)) {
					if(s.isElempty()||!matchs(s.pop().toString(),t)) {	//栈空或者栈顶元素与t分隔符不匹配
						throw new Exception("分隔符不匹配!");
					}
				}
			}
			if(!s.isElempty()) {
				throw new Exception("错误:有未匹配的分隔符!");
			}
		}else {
			throw new Exception("java语句为空!");
		}
		return true;
		
	}
	
	//主函数
	public static void main(String[] args) throws Exception {
		Example1_1 e = new Example1_1();
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入分隔符:");
		String come = sc.nextLine();
		if(e.isLegal(come)) {
			System.out.println("分隔符匹配!");
		}
	}
	
}

执行结果:
匹配成功:
分隔符匹配成功

匹配失败:
分隔符匹配失败
注意:
实现前需要创建一个顺序栈,若顺序栈是公共类,这个算法可以在与顺序栈的同一包下创建,否则需要导入顺序栈的包!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值