题目:
编写判断Java语句中分隔符是否匹配的问题。
分析:
java中的分隔符匹配有这几种情况:()、[]、{}、/**/。所以我们需要作的就是计算这些符号是否匹配问题,这个问题也是栈的典型应用场景之一。
思路:
遇到问题首先要想着化繁为简,我们首先可以看到,()、[]、{}这些都是的单个符号,/**/这是两个一起挨着的,我们就先从简单的入手,然后再考虑复杂的匹配。
1.对于写过代码的人都知道,符号都是成对出现,出现方式也只有两种要么是连着要么是([])这种结构的,思考一下不难发现使用栈来比较符号是否匹配是个不错的选择。
2.使用栈怎么比对呢?左符号入栈、碰到右符号就与栈顶比较,失败则说明不匹配,成功则让栈顶的左符号出栈。这样就完成了这几个简单元素的比对。那么复杂的双斜杠加星号怎么比较呢?
3.很显然,我们不可能一次就获取到/或者/,这两个的获取都不可能通过一次获得,因此我们可以通过for循环既拿到当前的也可以拿到他的下一位,然后单独比较该值即可。
代码实现:
1.栈
如果对于栈的实现不是太了解,或者懒的去实现一个栈结构,可以从这两篇文章里任意一篇进行借鉴:链栈、顺序栈。
笔者使用的是链栈来完成的这个题目。
2.代码实现
这里是整个代码的实现,上面给出的思路是一个大致的方向,细节代码里展示:
public class SymbolMatch { public static void main(String[] args) throws Exception{ System.out.println(symbolIfMatch("/**/(){}[]")); } public static boolean symbolIfMatch(String str) throws Exception{ LinkedStack linkedStack = new LinkedStack(); char[] strArray = str.toCharArray(); for(int i=0;i<strArray.length;i++){ String strnew = String.valueOf(strArray[i]); String strnewNext = ""; if(i<strArray.length-1) strnewNext = String.valueOf(strArray[i])+String.valueOf(strArray[i+1]); if(strnew.equals("(") ||strnew.equals("[") ||strnew.equals("{")){ linkedStack.push(strnew); } //单独处理该场景 if(strnewNext.equals("/*")){ linkedStack.push(strnewNext); } if(strnew.equals(")") ||strnew.equals("]") || strnew.equals("}")){ if(evaluateMatch(String.valueOf(linkedStack.peek()),strnew)){ //匹配成功出栈 linkedStack.pop(); }else{ return false; } } //单独处理该场景 if(strnewNext.equals("*/")){ if(evaluateMatch(String.valueOf(linkedStack.peek()),strnewNext)){ //匹配成功出栈 linkedStack.pop(); }else{ return false; } } } if(linkedStack.length()==0) return true; return false; } public static boolean evaluateMatch(String one,String two){ if(one.equals("(") && two.equals(")")){ return true; } if(one.equals("[") && two.equals("]")){ return true; } if(one.equals("{") && two.equals("}")){ return true; } if(one.equals("/*") && two.equals("*/")){ return true; } return false; } }
总结:
这是笔者看书时碰到的一个栈的应用问题,在这里记录下解决过程,这个题目的考察思路其实主要是栈的应用,题目的核心就是抓住符号的出现一个对称结构,即左符号与右符号的位置总是对称的无论中间有多少符号还是代码,有了这个特性我们就可以使用栈来解决类似问题。怎么说呢,这个问题就像套娃一样。