一种用Java解决括号匹配问题的方案:
题目:描述:给定一串由(、)、[、]、{、}组成的括号序列,输出最长的合法括号序列长度。合法括号序列定义如下:
- 空括号序列是合法的
- 若括号序列A合法,则(A)、[A]、{A}也是合法的
- 若括号序列A和B均合法,则AB也是合法的
输入:括号序列
输出:最长合法序列长度
样例1
输入:{}(((}}})))[[[]])
输出: 4
代码:
package FileIO;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import java.util.Stack;
public class ParenthesisMatch {
public static void main(String[] args) {
/*
//输入括号序列String
System.out.println("请输入一个括号序列:");
String parenthesisStr = new Scanner(System.in).next();
*/
String parenthesisStrTest="{}(((}}})))[[[]])";
//首先判断序列是否包含括号以外的非法字符
for (int i = 0; i <parenthesisStrTest.length() ; i++) {
char c=parenthesisStrTest.charAt(i);
if(c!='{' && c!='(' &&c!='[' &&c!=']' &&c!=')' &&c!='}' ){
System.out.println("序列包含括号以外的非法字符,请检查");
System.exit(0);
}
}
//创建栈对象用来存储括号
Stack<Character> stack=new Stack<>();
//记录一共出栈的次数,测试用
int popCount=0;
//元素入栈就往bigPopCount中加0,出栈就往bigPopCount加1,出栈都是左右括号两次连续出栈,故1的数目为偶数
ArrayList<Integer> bigPopCount=new ArrayList<>();
for (int i = 0; i < parenthesisStrTest.length();) {
// 判断栈中是否有>=2个元素,有则isTwoPiPei,无则i++,等待下一元素进栈
stack.push(parenthesisStrTest.charAt(i));
if(stack.size() < 2) {
//将chars[i]装入栈stack
i++;
//元素入栈就往bigPopCount中加0
bigPopCount.add(0);
}else {
//中间变量mediatechar接收栈顶元素
char mediatechar=stack.pop();
if (isTwoPiPei(stack.peek(),mediatechar)) {//比较栈顶-1元素与栈顶元素是否匹配,但不能破坏栈
/*
//栈顶元素删除了,应该重新入栈
stack.push(mediatechar);
peak元素入栈后出栈,这两句话抵消了
stack.pop();
*/
popCount++;
//出栈就往bigPopCount加1
bigPopCount.add(1);
stack.pop();
popCount++;
//System.out.println("执行了匹配后出栈");
//出栈就往bigPopCount加1
bigPopCount.add(1);
}else {
//栈顶元素删除了,为了不破坏栈,应该重新入栈
stack.push(mediatechar);
//元素入栈就往bigPopCount中加0
bigPopCount.add(0);
}
i++;
}
}
System.out.println("全部括号序列是否合法:"+stack.isEmpty());
System.out.println(("一共有合法序列长度:"+popCount));
System.out.println("bigPopCount:"+ bigPopCount);
//对bigPopCount中连续的1求区段和
ArrayList<Integer> bigPopCountSectionSum=new ArrayList<>();
int sum=0;
for (int i = 0; i < bigPopCount.size()-1; i++) {//一次读取两个
int singleleft=bigPopCount.get(i);
int singleright=bigPopCount.get(i+1);
if(singleleft == 0 && singleright==1){
//开始计数
sum++;
}
if(singleleft == 1 && singleright==1){
//继续计数
sum++;
}
if((singleleft == 1 && singleright==0 )||(singleleft == 1 && singleright==1 && i==bigPopCount.size()-2)){
//结束计数,上传连续1的区域和
bigPopCountSectionSum.add(sum);
//sum清零
sum=0;
}
}
System.out.println("bigPopCountSectionSum:"+bigPopCountSectionSum);
//获取bigPopCountSectionSum中最大值的返回
int max=0;
for (int element:bigPopCountSectionSum) {
if(element>max){
max=element;
}
}
System.out.println("最长合法序列长度:"+max);
}
//判断a,b是否是一对括号,a左b右返回true
public static boolean isTwoPiPei(char a,char b){
if(a == '{' && b== '}'){
return true;
}
if(a == '(' && b== ')'){
return true;
}
if(a == '[' && b== ']'){
return true;
}
return false;
}
}
```java
由于我也是初学者,并没有考虑更简单的算法,希望各位多多包涵。