If else vs switch with stack 逻辑
If else vs switch with stack logic
我正在通过编写一个验证括号语法的程序来学习堆栈。如果我输入 (Baller)
它应该给我一个肯定的结果。如果我有 (Baller()
它应该给我一个否定的结果。本质上,应用程序会检查用户是否正确使用了 ()、{} 和 []。
- 如果我遇到 ( 、{ 或 [ 字符,我会将其添加到
堆栈上的字符。
- 如果我遇到 ) } ] 符号,我将从堆栈中删除一个字符。
- 如果文本中包含奇数个圆括号或括号则不
连续的(例如,(和]不连续),错误
打印消息。
所以我在 if else 语句中完成了这一半,但我认为在 switch 语句中完成它应该更容易,并且也是一个很好的学习经验。
所以我在 switch 语句中所做的是这样的:
public class Input {
public static void main(String[] args) {
Stack stack = new Stack();
String str;
str = JOptionPane.showInputDialog("Text to parse: ");
char arr[] = str.toCharArray();
System.out.print(str);
System.out.println();
System.out.println();
for(char c : arr) {
switch(c) {
case '{':
stack.Push(c);
System.out.print(stack.firstNode.getData());
break;
case '(':
stack.Push(c);
System.out.print(stack.firstNode.getData());
break;
case '[':
stack.Push(c);
System.out.print(stack.firstNode.getData());
break;
case '}':
c = (Character) stack.Peek(); //<-- Edited for @Jimmy
if( c != '{') {
System.out.println(" Syntax ERROR");
}
case ']':
if( c != '[') {
System.out.println(" Syntax ERROR");
}
case ')':
if( c != '(') {
System.out.println(" Syntax ERROR");
}
}
}
}
}
但现在我遇到了一个问题,如果我只添加一个右侧括号,它就会被删除,因为我有一个流行音乐。我试图在一个 if-else 语句中做到这一点,该语句将以这样的 if-statement 结尾:
if(first == '(' && (current == '}' || current == ']')) {
if first == '{' && (current == ']' || current == ')')) {
//and so on
我怎样才能把它变成一个开关盒?这是一个坏主意吗?
据我所知,我的左侧支架确实没有问题,但右侧支架有问题。
编辑:代码现在的样子
import javax.swing.JOptionPane;
public class Input {
public static void main(String[] args) {
Stack stack = new Stack();
String str;
str = JOptionPane.showInputDialog("Text to parse: ");
char arr[] = str.toCharArray();
System.out.print(str);
System.out.println();
System.out.println();
for(char c : arr) {
switch(c) {
case '{':
stack.Push(c);
break;
case '(':
stack.Push(c);
break;
case '[':
stack.Push(c);
break;
case '}':
if(stack.isEmpty() || (Character) stack.Pop() != '{') {
System.out.println(" Syntax ERROR");
}
break;
case ']':
if(stack.isEmpty() || (Character) stack.Pop() != '[') {
System.out.println(" Syntax ERROR");
}
break;
case ')':
if(stack.isEmpty() || (Character) stack.Pop() != '(') {
System.out.println(" Syntax ERROR");
}
break;
}
} if(!stack.isEmpty()) {
System.out.println(" Syntax ERROR");
}
}
}
除了检查特定字符是否匹配外,还有两种情况需要有关堆栈本身的信息:
当括号数量不多时处于中间状态。当您尝试在堆栈为空时弹出时会发生这种情况。
当字符串末尾有孤立的括号时。在这种情况下,堆栈最终是非空的。
修正1,出栈前要检查栈是否为空:
case '}':
if (stack.empty()) {
System.out.println(" Syntax ERROR");
}
else {
c = (Character) stack.Pop();
if( c != '{') {
System.out.println(" Syntax ERROR");
}
}
break;
或等价地,
case '}':
if (stack.empty() || ((Character)stack.Pop()) != '{') {
System.out.println(" Syntax ERROR");
}
break;
要修复 2,在程序结束时,您应该检查堆栈 是否 为空。这捕获了尚未解决的 (bal)ler)
案例。
if (!stack.empty())
System.out.println(" Syntax ERROR");
}
好问题!很高兴您已经有了一个可行的解决方案并正在努力改进它。
您仍然可以使用 switch 语句,但在尝试弹出下一个值之前,您首先需要验证您的堆栈不为空。在我的实现中,我首先通过检查 stack.isEmpty()
并使用短路 OR 条件 ||
来进行检查。短路意味着如果 OR 条件的左侧为真,则右侧甚至不会被评估。
这是更新后的 for 循环。我不确定你用的是哪个 Stack class,所以我用的是 java.util.Stack
.
for(char c : arr) {
switch(c) {
case '{':
stack.push(c);
System.out.print(stack.peek());
break;
case '(':
stack.push(c);
System.out.print(stack.peek());
break;
case '[':
stack.push(c);
System.out.print(stack.peek());
break;
case '}':
if(stack.isEmpty() || (Character) stack.pop() != '{') {
System.out.println(" Syntax ERROR");
}
break;
case ']':
if(stack.isEmpty() || (Character) stack.pop() != '[') {
System.out.println(" Syntax ERROR");
}
break;
case ')':
if(stack.isEmpty() || (Character) stack.pop() != '(') {
System.out.println(" Syntax ERROR");
}
break;
}
}
编辑:我添加了缺失的 break;
语句。如果没有这些,系统将执行多个 case:
条件,因为它会对每个条件执行 'fall through'。
编辑 2:李宗政在他们的回答中提出了一个很好的观点。完成后,您应该验证堆栈中没有任何遗留字符。在你的循环之后,你应该有这样的东西:
if(!stack.isEmpty()) {
System.out.println(" Syntax ERROR");
}
编辑 3:将 stack.firstElement()
更改为 stack.peek()
。
你说你想学习如何使用 switch
语句。您可以使用一个巧妙的技巧,称为 falling through:
switch (c) {
case '{':
case '(':
case '[':
stack.Push(c);
System.out.print(stack.firstNode.getData());
break;
case '}':
case ']':
case ')':
if (stack.isEmpty() || stack.pop() != c) {
System.out.println("Syntax ERROR");
}
break;
}
我正在通过编写一个验证括号语法的程序来学习堆栈。如果我输入 (Baller)
它应该给我一个肯定的结果。如果我有 (Baller()
它应该给我一个否定的结果。本质上,应用程序会检查用户是否正确使用了 ()、{} 和 []。
- 如果我遇到 ( 、{ 或 [ 字符,我会将其添加到 堆栈上的字符。
- 如果我遇到 ) } ] 符号,我将从堆栈中删除一个字符。
- 如果文本中包含奇数个圆括号或括号则不
连续的(例如,(和]不连续),错误
打印消息。
所以我在 if else 语句中完成了这一半,但我认为在 switch 语句中完成它应该更容易,并且也是一个很好的学习经验。
所以我在 switch 语句中所做的是这样的:
public class Input {
public static void main(String[] args) {
Stack stack = new Stack();
String str;
str = JOptionPane.showInputDialog("Text to parse: ");
char arr[] = str.toCharArray();
System.out.print(str);
System.out.println();
System.out.println();
for(char c : arr) {
switch(c) {
case '{':
stack.Push(c);
System.out.print(stack.firstNode.getData());
break;
case '(':
stack.Push(c);
System.out.print(stack.firstNode.getData());
break;
case '[':
stack.Push(c);
System.out.print(stack.firstNode.getData());
break;
case '}':
c = (Character) stack.Peek(); //<-- Edited for @Jimmy
if( c != '{') {
System.out.println(" Syntax ERROR");
}
case ']':
if( c != '[') {
System.out.println(" Syntax ERROR");
}
case ')':
if( c != '(') {
System.out.println(" Syntax ERROR");
}
}
}
}
}
但现在我遇到了一个问题,如果我只添加一个右侧括号,它就会被删除,因为我有一个流行音乐。我试图在一个 if-else 语句中做到这一点,该语句将以这样的 if-statement 结尾:
if(first == '(' && (current == '}' || current == ']')) {
if first == '{' && (current == ']' || current == ')')) {
//and so on
我怎样才能把它变成一个开关盒?这是一个坏主意吗?
据我所知,我的左侧支架确实没有问题,但右侧支架有问题。
编辑:代码现在的样子
import javax.swing.JOptionPane;
public class Input {
public static void main(String[] args) {
Stack stack = new Stack();
String str;
str = JOptionPane.showInputDialog("Text to parse: ");
char arr[] = str.toCharArray();
System.out.print(str);
System.out.println();
System.out.println();
for(char c : arr) {
switch(c) {
case '{':
stack.Push(c);
break;
case '(':
stack.Push(c);
break;
case '[':
stack.Push(c);
break;
case '}':
if(stack.isEmpty() || (Character) stack.Pop() != '{') {
System.out.println(" Syntax ERROR");
}
break;
case ']':
if(stack.isEmpty() || (Character) stack.Pop() != '[') {
System.out.println(" Syntax ERROR");
}
break;
case ')':
if(stack.isEmpty() || (Character) stack.Pop() != '(') {
System.out.println(" Syntax ERROR");
}
break;
}
} if(!stack.isEmpty()) {
System.out.println(" Syntax ERROR");
}
}
}
除了检查特定字符是否匹配外,还有两种情况需要有关堆栈本身的信息:
当括号数量不多时处于中间状态。当您尝试在堆栈为空时弹出时会发生这种情况。
当字符串末尾有孤立的括号时。在这种情况下,堆栈最终是非空的。
修正1,出栈前要检查栈是否为空:
case '}':
if (stack.empty()) {
System.out.println(" Syntax ERROR");
}
else {
c = (Character) stack.Pop();
if( c != '{') {
System.out.println(" Syntax ERROR");
}
}
break;
或等价地,
case '}':
if (stack.empty() || ((Character)stack.Pop()) != '{') {
System.out.println(" Syntax ERROR");
}
break;
要修复 2,在程序结束时,您应该检查堆栈 是否 为空。这捕获了尚未解决的 (bal)ler)
案例。
if (!stack.empty())
System.out.println(" Syntax ERROR");
}
好问题!很高兴您已经有了一个可行的解决方案并正在努力改进它。
您仍然可以使用 switch 语句,但在尝试弹出下一个值之前,您首先需要验证您的堆栈不为空。在我的实现中,我首先通过检查 stack.isEmpty()
并使用短路 OR 条件 ||
来进行检查。短路意味着如果 OR 条件的左侧为真,则右侧甚至不会被评估。
这是更新后的 for 循环。我不确定你用的是哪个 Stack class,所以我用的是 java.util.Stack
.
for(char c : arr) {
switch(c) {
case '{':
stack.push(c);
System.out.print(stack.peek());
break;
case '(':
stack.push(c);
System.out.print(stack.peek());
break;
case '[':
stack.push(c);
System.out.print(stack.peek());
break;
case '}':
if(stack.isEmpty() || (Character) stack.pop() != '{') {
System.out.println(" Syntax ERROR");
}
break;
case ']':
if(stack.isEmpty() || (Character) stack.pop() != '[') {
System.out.println(" Syntax ERROR");
}
break;
case ')':
if(stack.isEmpty() || (Character) stack.pop() != '(') {
System.out.println(" Syntax ERROR");
}
break;
}
}
编辑:我添加了缺失的 break;
语句。如果没有这些,系统将执行多个 case:
条件,因为它会对每个条件执行 'fall through'。
编辑 2:李宗政在他们的回答中提出了一个很好的观点。完成后,您应该验证堆栈中没有任何遗留字符。在你的循环之后,你应该有这样的东西:
if(!stack.isEmpty()) {
System.out.println(" Syntax ERROR");
}
编辑 3:将 stack.firstElement()
更改为 stack.peek()
。
你说你想学习如何使用 switch
语句。您可以使用一个巧妙的技巧,称为 falling through:
switch (c) {
case '{':
case '(':
case '[':
stack.Push(c);
System.out.print(stack.firstNode.getData());
break;
case '}':
case ']':
case ')':
if (stack.isEmpty() || stack.pop() != c) {
System.out.println("Syntax ERROR");
}
break;
}