if if vs switch with stack logic

时间:2015-09-10 19:43:01

标签: java if-statement stack switch-statement

我正在通过编写验证括号语法的程序来学习堆栈。如果我输入(Baller),它应该给我一个积极的结果。如果我有(Baller(),它应该给我一个否定的结果。本质上,应用程序检查用户是否正确使用了(),{}和[]。

  • 如果我遇到(,{,或[字符我会将其添加到 堆栈上的字符。
  • 如果我遇到a)}]符号,我将从堆栈中删除一个字符。
  • 如果文本包含奇数个括号或括号不包含 连续的(例如,(和)不连续),错误
    消息已打印。

所以我在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语句结束:

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");
        }
    }
}

2 个答案:

答案 0 :(得分:4)

好问题!很高兴您已经有了可行的解决方案并且正在努力改进它。

您仍然可以使用switch语句,但在尝试弹出下一个值之前,首先需要验证堆栈是否为空。在我的实现中,我首先检查stack.isEmpty()并使用短路OR条件||进行检查。短路意味着如果OR条件的左侧为真,那么右侧甚至不会被评估。

这是更新的for循环。我不确定您正在使用哪个Stack类,因此我正在使用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:条件,因为它将会通过&#39;每个人。

编辑2:Zong Zheng Li在答案中提出了一个很好的观点。您应该在完成后验证堆栈中是否还有剩余字符。循环之后,你应该有这样的东西:

if(!stack.isEmpty()) {
    System.out.println("  Syntax ERROR");
}

编辑3:将stack.firstElement()更改为stack.peek()

答案 1 :(得分:2)

除了检查特定字符是否匹配之外,还有两种情况需要有关堆栈本身的信息:

  1. 当中间状态中括号的数量不多时。当您尝试在堆栈为空时弹出时会发生这种情况。

  2. 当字符串末尾有孤立括号时。在这种情况下,堆栈最终非空。

  3. 要修复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");
    }