需求:
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效,有效字符串需满足:
1、左括号必须用相同类型的右括号闭合。
2、左括号必须以正确的顺序闭合。
分析:
首先要联想到用哪一种数据结构,可以先写一个正确的字符串,然后观察如何比较......能不能想到用栈那就要看悟性了,有点尴尬。可以先写一个:{[()]} 类似于这样的字符串,然后用栈先实现出来一个简单的版本,然后再去考虑一些特殊的情况。
源码:
private static boolean isValidBrackets(String s) {
if (null == s) {// @1
return false;
}
if ("".equals(s)) {// @2
return true;
}
char[] chars = s.toCharArray();
Stack<Character> stack = new Stack<>();
for (Character character: chars) {
if (character == '(') {
stack.push(')');
} else if (character == '[') {
stack.push(']');
} else if (character == '{') {
stack.push('}');
} else if (stack.size() == 0 || character != stack.pop()) {// @3
return false;
}
}
if (stack.size() > 0)// @4
return false;
return true;
}
源码简单分析:@1和@2 都是对边界值的校验,@3 是核心校验逻辑,包括两种情况:
1、左边第一个字符是}])中的一个,也就是栈的大小等于0。
2、当碰到类似于}])的字符时,会和栈里面的数据做比较,不等于就返回false。
@4: 如果所有的字符串都比较完之后,stack里面还有值的话,说明括号不是一一对应的,返回false。
总结:
栈是一种先进后出的数据结构,这个前提要知道。另外写代码的过程中,不可能一口气写出来完整的代码的,先写出核心代码,然后再去考虑一些边界值和一些特殊情况。特别是在测试取值的时候,一些边界值和特殊值还是要考虑到位,考虑的越到位,bug越少,bug是永远不会消灭完的,所以我们要永远的学习,让自己的代码变得更健壮。
其实换种思路,我们还可以先写测试用例,然后再根据测试用例去写代码,测试驱动开发。其实,这是一个编程习惯,需要慢慢的养成,我个人认为测试驱动开发,还是挺好的,会让你对自己的代码要实现什么功能会更清楚,一旦测试用例写完,以后如果再去修改这部分代码,直接运行测试用例来检查就可以了,可以保证自己代码的质量。效率只会越来越高,特别是后期......快乐coding......
网友评论