栈是限制插入和删除操作只能在一个位置上进行的表,该操作的位置是在表的末端的叫做栈。对栈常用的操作有压栈,出栈。栈有时候也叫做后进先出的表。
栈的实现方式有两种:
第一种方式是使用单链表。通过在表的顶端插入来实现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为支持的可以匹配符号的所有符号
匹配结果为:
本文介绍了栈作为后进先出数据结构的基本概念,并探讨了两种实现方式:单链表和数组。通过Java的LinkedList类,作者展示了如何封装一个栈类Stack,用于处理符号匹配问题。文章中,作者提出了一个匹配成对符号(如()、{}、[])的算法,从左到右遍历样本,遇到开放符号压栈,遇到关闭符号时与栈顶元素比较,匹配成功则出栈。文章还提到可以通过配置文件扩展匹配符号。
2855

被折叠的 条评论
为什么被折叠?



