数据结构Java实现——①栈-->栈的应用二、分隔符匹配

写在前面


只是学栈的描述之类的似乎很无聊,所以我特意找了几个比较有意思的例子,一则加深对栈的理解和运用,二则,也可以开拓一下思路,此处为例二


例二、分隔符匹配问题


1、问题描述


编译器在编译一段代码时,首先进行的就是分隔符的匹配,常见的分隔符有{   } [   ]  (   )/*  */

2、思路


首先要知道的一件事就是:分隔符运行嵌套,而且,读入的顺序和处理的顺序相反,很显然是用栈。
算法描述如下: 从左到右扫描java语句,从语句中不断的读取字符,每次读取一个字符,若发现它是左分割符,则将它压入栈;
当从输入中读到一个右分割符时,则弹出栈顶 的左分隔符,并且查看它是否和右分隔符匹配,若它们不匹配,则匹配失败,程序报错;  
若栈顶没有左分隔符与右分隔符匹配,或者一直存在没有被匹配的左分隔符,左分隔符没有被匹配, 表现为所有的字符都读入后,栈中仍然有左分隔符,则匹配失败,程序报错; 
若所有的字符读入结束后,栈为空,则表示匹配成功

3、代码实现

package org.Stone6762.MStack.adopt;

import java.util.Scanner;

import org.Stone6762.MStack.imple.SqStack;

/**
 * @author_Stone6762
 */
public class MatchTest {

	/**
	 * @LEFT记录分隔符为“左”分隔符
	 */
	private final int LEFT = 0;

	/**
	 * @RIGHT记录分隔符为“右”分隔符
	 */
	private final int RIGHT = 1;

	/**
	 * @OTHER记录其他字符
	 */
	private final int OTHER = 2;

	/**
	 * @MAXSIZE栈的大小_也就是整个程序中的左分隔符的个数的最大值
	 */
	private final int MAXSIZE = 100;

	/**
	 * @Describe_判断分隔符的类型_左_右_非法
	 * @param str
	 * @return
	 */
	public int verifyFlag(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;

		}

	}

	/**
	 * @Describe_判断左分隔符str1和右分隔符str2是否匹配
	 * @param str1
	 * @param str2
	 * @return
	 */
	public boolean matches(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;
		}
	}

	/**
	 * @Describe_判断是否匹配
	 * @param str
	 * @return
	 * @throws Exception
	 */
	public boolean isLegal(String str) throws Exception {
		if (!"".equals(str) && str != null) {
			SqStack S = new SqStack(MAXSIZE);
			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 == verifyFlag(t)) {
					S.push(t);
				} else if (RIGHT == verifyFlag(t)) {
					if (S.isEmpty()) {
						throw new Exception("错误:   java语法不合法,缺少左分隔符");
					} else if (!matches(S.pop().toString(), t)) {
						throw new Exception("错误:   java语法不合法,左右分隔符不匹配");
					}
				}
			}
			// 对整个语句遍历后,如果栈非空,证明栈中还有未被匹配的左分隔符,此时是错误的
			if (!S.isEmpty()) {
				throw new Exception("错误: java语句不合法,缺少右分隔符");
			} else {
				return true;
			}
		} else {
			throw new Exception("错误:Java语句为空 ! ");
		}
	}

	public static void main(String[] args) throws Exception {
		MatchTest m = new MatchTest();
		Scanner scan = new Scanner(System.in);
		System.out.println("请输入 想要判断 java语句");
		while (scan.hasNext()) {
			if (m.isLegal(scan.nextLine())) {
				System.out.println("Java语句正确");
			} else {
				System.out.println("错误:Java语句不合法");
			}
			System.out.println();
			System.out.println("请输入 想要判断 java语句");
		}
	}
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值