❗❗❗必看:
下列题我全部都使用 Java 语言写的,并且均可以提交成功,获得Accepted 结果的. 如果代码和详解看了之后,对答案有任何疑问,都可以在评论区提出来,我都会一个一个回答.
❗❗❗感谢大家的支持,如果喜欢我的博客,关注 点赞 收藏 评论一波,非常感谢!!!
题目:括号匹配问题
在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号。不能匹配的左括号用"$“标注,不能匹配的右括号用”?"标注.
Input
输入包括多组数据,每组数据一行,包含一个字符串,只包含左右括号和大小写字母,字符串长度不超过100
注意:cin.getline(str,100)最多只能输入99个字符!
Output
对每组输出数据,输出两行,第一行包含原始输入字符,第二行由"“,”?“和空格组成,”“,”?“和空格组成,”“和”?"表示与之对应的左括号和右括号不能匹配。
测试样例
输入
((ABCD(x)
)(rttyy())sss)(
输出
((ABCD(x)
$$
)(rttyy())sss)(
? ?$
代码
import java.util.Scanner;
import java.util.Stack;
public class Main{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while(scanner.hasNextLine()) {
String input = scanner.nextLine();
Stack<Integer> stack = new Stack<>();
char[] chars = input.toCharArray();
StringBuilder marks = new StringBuilder();
//初始标记marks所有的值为一个空格值
for(int i=0;i<chars.length;i++) {
marks.append(' ');
}
//遍历字符串,找出无法匹配的括号
for(int i = 0;i<chars.length;i++) {
if(chars[i]=='('){
stack.push(i);
}else if(chars[i]==')') {
if(stack.isEmpty()) {
marks.setCharAt(i, '?');
}else {
stack.pop();
}
}
}
//找出栈中所有的左括号
while(!stack.isEmpty()) {
marks.setCharAt(stack.pop(),'$');
}
System.out.println(input);
System.out.println(marks.toString());
}
scanner.close();
}
}
详解
初步思路
使用栈数据结构来匹配括号,因为栈遵循后进先出(LIFO)的特性,适合处理这种成对出现的问题。
具体步骤
- 初始化:创建一个栈来存储左括号的位置,并创建一个字符串构建器来标记无法匹配的括号,初始标记为所有空格。
- 遍历字符串:
- 遇到左括号时,将其索引压入栈中。
- 遇到右括号时,检查栈是否为空:
- 如果栈不为空,则弹出栈顶元素(表示一个左括号和当前右括号匹配)。
- 如果栈为空,则说明当前右括号没有匹配的左括号,用 ? 标记该位置。
- 处理剩余的左括号:
- 遍历栈中剩余的左括号索引,将这些位置用 $ 标记,表示这些左括号没有匹配的右括号。
- 输出结果:
- 输出原始输入字符串。
- 输出标记字符串,标记字符串中显示无法匹配的括号位置。
总结方法
通过栈数据结构,我们可以方便地跟踪括号匹配问题。每次遇到右括号时,检查栈顶的左括号是否匹配。如果匹配,则弹出栈顶元素;否则,标记当前右括号为未匹配。最终处理栈中剩余的左括号,标记为未匹配。这个方法具有启发性,可以扩展到其他需要成对匹配的数据结构问题中。