栈的应用之进制转换、括弧匹配(单括弧、多括弧)
进制转换
只要掌握十进制转二进制的短除法,就能理解下面的
文字解说
和代码实现
了
文字解说:
既然说到了栈——那要将什么东西与栈相关呢?栈的特点是什么呢?
- 自然是余数了。将余数push进栈,等数值不能再相除时【意思就是n>0即不能再相除了】,打印余数出栈。
- 栈一定是先进后出的
代码实现:
public class reConversionTest {
/**
* 测试类
* @param args
*/
public static void main(String[] args) {
String result = conversion(100,2);
System.out.println(result);
}
/**
*
* @param n 十进制数
* @param decimal 需要转换的进制
* @return 返回已经转好了的数
*/
public static String conversion(int n, int decimal){
/**
* 思路:
* 既然说到了栈---那要将什么东西与栈相关呢?
* 自然是余数了,熟悉十进制转二进制的短除法就能明白这种操作了
*
*/
Stack<Integer> stack = new Stack<>();
while (n >= 1){
int i = n%decimal;
stack.push(i);
n = n/decimal;
}
//出栈打印操作
StringBuffer stringBuffer = new StringBuffer();
while ( !stack.isEmpty()){
stringBuffer.append(stack.pop());
}
return stringBuffer.toString();
}
}
括弧匹配
括弧匹配思路也很简单,不要被穿插着注释的代码唬住
单括弧匹配
以小括号为例
文字思路:
-
因为括号有两边,我们使用最佳的数据结构-------栈,装入一边的括号(以 左括号 为例)
-
遍历给定的字符串,遇到左括号,我们就把它入栈
-
然后继续往后遍历,遇到右括号,我们就弹出一个左括号。【注意:如果栈中没有左括号呢,说明没有和右括号匹配的左括号,那我们就直接返回false】
你以为就完事了吗?no no no
- 如果栈中还剩余左括号,字符串已经遍历完毕,也是不匹配的。我们就用size()方法来判断栈中是否还留有左括号
考虑两个方面:一是原字符串的遍历之入栈、出栈,即分出左括弧、右括弧;二是栈的元素有没有剩余,若有剩余,即为左括弧有多余不匹配
代码实现:
public class reBracketsMatchTest {
public static void main(String[] args) {
String st = "上海(宝钢)北{(){}京(天安门)";
boolean flag1 = matchChars(st);
System.out.println("该字符串是否匹配?" + flag1); //true
}
/**
*
* @param str
*/
private static boolean matchChars(String str){
/**
* 匹配思路:
* 题目:先给定一个字符串,判断括号是否匹配
* 思路:
* 因为括号有两边,我们使用最佳的数据结构---栈,装入一边的括号(以左括号为例)
* 遍历给定的字符串,遇到左括号,我们就把它入栈
* 然后继续往后遍历,遇到右括号,我们就弹出一个左括号。【注意:如果栈中没有左括号呢,说明没有和右括号匹配的左括号,那我们就直接返回false】
* 你以为就完事了吗?no no no
* 如果栈中还剩余左括号,字符串已经遍历完毕,也是不匹配的。我们就用size()方法来判断栈中是否还留有左括号
*/
Stack<String> chars = new Stack<>();
for (int i = 0; i < str.length(); i++){
String c = str.charAt(i) +"";
if (c.equals("(")){
chars.push(c);
}else if (c.equals(")")){
if (chars.isEmpty()){
return false;
}
chars.pop();
}
}
return chars.size()==0;
}
多括弧匹配
以小括号、中括号、大括号为例
文字思路:
和 单括弧匹配 思路差不多,唯一不同的就是 出栈 时【意思就是遇见右括弧再加一步判断操作】需要判断是哪一种括弧,使用switch语句
代码实现:
public class reBracketsMatchTest {
public static void main(String[] args) {
String st = "上海(宝钢)北{(){}京(天安门)";
boolean flag2 = bracketM(st);
System.out.println("该字符串是否匹配?" + flag2); //false
}
/**
* 匹配三组括弧
* @param str
* @return
*/
public static boolean bracketM(String str){
/**
* 思路:
* 因为括弧有两边,最佳的方法利用数据结构--栈来实现
* 遍历给定的字符串,遇见左一边的括弧,我们就将它入栈
* 再遍历后面的字符,遇见右一边的括弧,我们就将它弹出。【注意:如果栈为空,直接返回false;如果栈不为空,判断是哪种括弧,我们再弹栈】
* 还没完呢!一方面的字符串遍历完了,还有一方面的栈没有判断还有没有剩余【意思为,左一边的符号有没有多,多了也是匹配错误】
*/
Stack<String> stack = new Stack<>();
for (int i = 0; i < str.length(); i++){
String c = str.charAt(i) + "";
switch(c){
case("("):
case("["):
case("{"):
stack.push(c);
break;
case("}"):
if (!stack.isEmpty() && c.equals("}")){
stack.pop();
}
case("]"):
if (!stack.isEmpty() && c.equals("]")){
stack.pop();
}
case(")"):
if (!stack.isEmpty() && c.equals(")")){
stack.pop();
}
}
}
return stack.size() == 0;
}
}