问题引入
在Java的表达式中分隔符有左分隔符("(","{","[","/*")和 右分隔符(")","}","]","/"),那么我们应该怎样编写一个程序来判断一个字符串表达式中的分隔符是否完全匹配呢?
算法分析
在解决分隔符匹配问题中常见的错误思想:
通过两个计数器分别记录左分隔符和右分隔符的个数,如果扫描完字符串两个计数器记录的值相等则认为分隔符是匹配的。通过这种算法得到的结果其实很有可能是错误的,因为这种算法并没有考虑分隔符匹配具有的先后性,像"))(("这样的字符串得到的结果也会是匹配的,但是很明显事实上这个是分隔符不匹配的
那么我们该怎么样解决分隔符匹配的问题呢?这个时候就可以用到栈这个工具了,这个问题中栈的具体使用是用来存储左分隔符。
- 首先,我们扫描字符串,遇到左分隔符("(","{","[","/*")*就进行入栈操作
- 如果遇到右分隔符(")","}","]","*/"),要分情况讨论:①栈为空,即没有遇到左分隔符或者之前的分隔符都已经完全匹配好了,那么很明显此时这个右分隔符是没有一个左分隔符与之匹配的,就像"(())]“②栈不为空,但是右分隔符与栈顶的左分隔符并不匹配,那么也很明显此时是不匹配的,就像”((]"③栈不为空且此时右分隔符与栈顶的左分隔符是匹配的,那么栈顶的左分隔符就可以出栈了
- 重复上述步骤,直至字符串全部扫描完,如果扫描完以后栈为空说明分隔符是完全匹配的,栈不为空则说明分隔符不是完全匹配
代码实现
链栈LinkStack的实现可以参考:https://blog.csdn.net/qq_52486831/article/details/120795153
package linkStack;
/*
* @Date:2021-10-16
* @Author:不知心动
* 栈的应用之分隔符匹配问题
*/
public class SignMatch {
// 判断表达式的左右分隔符是否匹配
public boolean signMatch(String str) throws Exception {
if (str != null && !"".equals(str)) {
boolean flag = true;
//我习惯使用链栈,使用顺序栈也是一样的
LinkStack stack = new LinkStack();
for (int i = 0; i < str.length(); i++) {
//接受字符串对应位置的字符,方便后面进行字符串的拼接
char c = str.charAt(i);
String s = String.valueOf(c);
System.out.print(s+" ");
//扫描遇到空格直接跳过
if (" ".equals(s)) {
continue;
}
//特殊一点的分隔符有"/*"和"*/",这两个分隔符长度为2,其余的分隔符长度都为1,所以要单独讨论,如果遇到要进行字符串的拼接,同时要跳过一个字符
if ("/".equals(s) && i < str.length() - 1 && &