栈的简单应用—-符号匹配

本文介绍了栈作为后进先出数据结构的基本概念,并探讨了两种实现方式:单链表和数组。通过Java的LinkedList类,作者展示了如何封装一个栈类Stack,用于处理符号匹配问题。文章中,作者提出了一个匹配成对符号(如()、{}、[])的算法,从左到右遍历样本,遇到开放符号压栈,遇到关闭符号时与栈顶元素比较,匹配成功则出栈。文章还提到可以通过配置文件扩展匹配符号。

栈是限制插入和删除操作只能在一个位置上进行的表,该操作的位置是在表的末端的叫做栈。对栈常用的操作有压栈,出栈。栈有时候也叫做后进先出的表。

栈的实现方式有两种:

第一种方式是使用单链表。通过在表的顶端插入来实现push(入栈),通过删除表顶端元素实现pop(出栈)。

第二种方式是数组方式:模仿ArrayList的add方法操作,因此相应的实现方法很简单。

java在集合框架中提供了LinkedList类对象,该类提供了一栈的操作 。不过此处还是自己简单的封装了一个类用于实现栈功能(如果想了解栈的实现结构可以参看后面的C语言实现的栈)

类Stack.java实现的是一个栈的基本功能,在内部调用了LinkedList类中提供的一系列方法。

import java.util.LinkedList;


public class Stack<T> {
	private LinkedList<T> stack = new LinkedList<T>();
	//入栈
	public T push(T value){
		stack.addFirst(value);
		return value ;
	}
	//出栈
	public T pop(){
		return stack.pop();
	}
	//取栈顶元素
	public T top(){
		if(stack.isEmpty())
			return null ;
		return stack.getFirst();
	}
	//是否栈空
	public boolean isEmpty(){
		return stack.isEmpty();
	}
}
实现栈很简单,那么栈到底在什么时候用得到呢 ?栈的用处很多,比如:后缀表达式、中缀后缀的转换和下面作为例子实现的平衡符号。

功能描述:从样本文件中输入样本,然后匹配成对的符号的个数并将这些符号输出到控制台。匹配成功的符号为:一个开放符号匹配一个关闭符号为一对(如: ()、{} 、[] 等)。此处为了练习还能支持添加可以匹配符号的样本。

实现思路:样本串中的内容从左到右一次取出,每次取出一个匹配是否是开放符号(左)如果是则入栈,如果不是则将取出的符号和支持判断的符号相比较。如果成功则表示是一对完整的,反之则不是。实现代码如下:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Properties;

public class BalanceMark {
	/*
	 * 本示例实现一个平衡符号的应用。
	 *  步骤:首先从一个文件中读入内容,判断符号是否是成对的,如:{}()[]这样的符号才是成对的 否则不能匹配
	 */
	
	public static void main(String[] args) throws Exception {
		int count = 0 ;
		Stack<String> stack = new Stack<>();
		//输入流,读取需要匹配的样本
		BufferedReader buffr = new BufferedReader(new FileReader("sample.txt"));
		//创建输入流,读取支持匹配的符号
		InputStream isp = BalanceMark.class.getResourceAsStream("mark.properties");
		Properties prop = new Properties();
		//加载支持符号的流对象
		prop.load(isp);
		String line = null;
		StringBuilder sb = new StringBuilder();
		//将所有样本读取出来
		while ((line = buffr.readLine()) != null) {
			sb.append(line);
		}
		buffr.close();
		//取出所有支持的符号的"开"(左边)
		Enumeration<String> em = (Enumeration<String>) prop.propertyNames();
		StringBuilder keys = new StringBuilder();
		StringBuilder value = new StringBuilder();
		while (em.hasMoreElements()) {
			String key = em.nextElement();
			keys.append(key);
			//右边符号
			value.append(prop.getProperty(key));
		}
		String startMark = new String(keys); //"<{[(";
		String endMark = new String(value); //">}])";
		//存放结果
		StringBuilder result = new StringBuilder() ;
		//匹配
		for (int x = 0; x < sb.length(); x++) {
			String ch = String.valueOf(sb.charAt(x));
			//如果是开放符号就入栈
			if (startMark.contains(ch)) {
				stack.push(ch);
			} else if (endMark.contains(ch)) {
				if (stack.top() != null) {
					//如果栈顶元素和和当前取出的是成对的则添加到结果集中
					if (prop.getProperty(stack.top()).equals(ch)) {
						result.append(stack.pop() + ch +" ");
						count++ ;
					}
				}
			}
		}
		System.out.println(result);
		System.out.println(count);
		isp.close();
	}
}
输入带匹配的样本为:(<>)<<)>>(()>(()))><<>>(){}{}{{[[}}]]()((([[[[][][][][][[[]][]]}

配置文件mark.properties为支持的可以匹配符号的所有符号

匹配结果为:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值