Java解决括号匹配算法问题

有效字符串需满足:

左括号必须用相同类型的右括号闭合。包括:“( )”,“[ ]”,“{ }”。 左括号必须以正确的顺序闭合。 注意空字符串可被认为是有效字符串。

思路:在这里我们使用栈来实现。遍历字符串时判断:如果是左括号,那么我们将其入栈;如果为右括号,我们先判断栈是否为空(有可能字符串刚开始就是一个右括号呢),为空的话直接返回false,不为空时判断:栈顶元素和下一个要入栈的元素是否相匹配,若匹配就出栈元素,若不匹配,返回false。

又因括号种类比较多,且存在${}这种括号不是单个字符的问题, 所以引入双向map,增强其扩展性。

代码如下:

1import org.apache.commons.collections4.BidiMap; 2import org.apache.commons.collections4.bidimap.DualHashBidiMap; 3import org.junit.Assert; 4import org.junit.Test; 5 6import java.util.HashMap; 7import java.util.Map; 8import java.util.Stack; 9 10/** 11 * @author : 杨松<yangsong158@qq.com> 12 * @date : 2020/4/3 13 * @desc : 14 */ 15public class BracketPairTest { 16 17 public boolean pairCheck(Map<String,String> pairMap,String expr) { 18 if (expr == null || expr == "") throw new NullPointerException("表达式为空"); 19 //双向Map解决括号匹配问题 20 BidiMap<String,String> bracketMap = new DualHashBidiMap(); 21 bracketMap.putAll(pairMap); 22 23 Stack<String> stack = new Stack<String>(); 24 25 StringBuffer overlap = new StringBuffer(); //叠加器,解决括号不为一个字符的问题 26 int overlapMaxLen = 2; //叠加器,最大叠加字符数 27 for (int i = 0; i < expr.length(); i++) { 28 String word = expr.substring(i,i+1); 29 overlap.append(word); 30 String overlapWord = overlap.toString(); 31 if(bracketMap.containsKey(word)){ 32 stack.push(word); 33 }else if(bracketMap.containsKey(overlapWord)){ 34 stack.push(overlapWord); 35 }else{ 36 if(bracketMap.containsValue(word)){ //右半部分括号 37 String left = bracketMap.getKey(word); //找左半部分括号 38 if (!stack.empty() && stack.peek().equals(left)) { //栈顶元素和括号对中的左半括号相同,则匹配,出栈 39 stack.pop(); 40 } 41 }else if(bracketMap.containsValue(overlapWord)){ //单独处理下叠加器中涉及括号有多个字符的问题 42 String left = bracketMap.getKey(overlapWord); 43 if (!stack.empty() && stack.peek().equals(left)) { 44 stack.pop(); 45 } 46 } 47 } 48 //叠加器超过满最大个数,清空最前面的字符 49 if(overlap.length()==overlapMaxLen) overlap.deleteCharAt(0); 50 } 51 52 if (stack.empty()) 53 return true; 54 return false; 55 } 56 57 @Test 58 public void pairCheckTest(){ 59 //1.设置括号对 60 Map<String,String> bracketMap = new HashMap(){{ 61 put("{", "}"); 62 put("[", "]"); 63 put("(", ")"); 64 put("<$", ">"); 65 put("【※", "※】"); 66 }}; 67 //2.验证是否通过 68 Assert.assertTrue(pairCheck(bracketMap,"()")); 69 Assert.assertTrue(pairCheck(bracketMap,"()[]")); 70 Assert.assertTrue(pairCheck(bracketMap,"()[]{}")); 71 Assert.assertTrue(pairCheck(bracketMap,"{[]}")); 72 Assert.assertTrue(pairCheck(bracketMap,"{[()]}")); 73 Assert.assertTrue(pairCheck(bracketMap,"{((1+3)+2+4)+9*7}")); 74 Assert.assertTrue( pairCheck(bracketMap,"{[(<$这是一段内容>)]}")); 75 Assert.assertFalse(pairCheck(bracketMap,"{[(<$这是一段内容)]}")); 76 Assert.assertTrue(pairCheck(bracketMap,"{[(【※变量测试※】)]}")); 77 Assert.assertFalse(pairCheck(bracketMap,"{[(【※变量测试】)]}")); 78 } 79 80}
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java实现判断两个二叉树是否相同

1、定义树节点类:节点值、左节点、右节点、构造器2、先判断树是否为空的情况3、树不为空时,判断节点所指的值是否相等,若相等,则递归判断节点的左右节点是否相同,相同则返回true/\\ \Definitionforbinarytree \publicclassTreeNode{ \    intval

SpringBoot自定义序列化的使用方式

场景及需求:项目接入了SpringBoot开发,现在需求是服务端接口返回的字段如果为空,那么自动转为空字符串。例如:\    {        "id":1,        "name":null    },    {        "id":2,        "name":"x