2015-09-10 3 views
4

Я изучаю стеки, написав программу, которая проверяет синтаксис скобок. Если я нахожу (Baller), он должен дать мне положительный результат. Если у меня есть (Baller(), он должен дать мне отрицательный результат. По сути, приложение проверяет правильность использования пользователя(), {} и [].Если else vs switch with stack logic

  • Если я встречаю ({или [персонаж я добавлю его в символ в стеке.
  • Если я встречаю)}] знак я удалить символ из стека.
  • Если текст содержит нечетное число скобок или скобки не являются смежными (например, (и] не является непрерывным), ошибка
    сообщение об распечатывается.

Так что я сделал это половина . в случае еще заявление, но я подумал, что это должно быть легче сделать это в распределительном заявление, а также быть хороший опыт обучения

Так что я сделал в заявлении выключателя заключается в следующем:

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(first == '(' && (current == '}' || current == ']')) { 
if first == '{' && (current == ']' || current == ')')) { 
//and so on 

Как я могу превратить это в случае переключения? Это плохая идея?

Я знаю, что на моей левой боковой панели нет проблем, но есть правильные.

EDIT: Как выглядит код ПРЯМО СЕЙЧАС

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

вы можете использовать peek(), который просто позволит вам увидеть последнее содержимое стека. Если нет ошибки, вы можете вызвать pop(), иначе не вызывать поп, и он не будет удален. – Jimmy

+0

@Jimmy Не могли бы вы привести пример, как он будет работать в коде? В противном случае, где вы хотели изменить? – Thrillofit123

+0

что-то вроде этого в вашем первом случае удаления .i.e для случая '}': 'c = (Character) stack.Peek(); if (c! = '{') { System.out.println ("Синтаксис ERROR"); } else stack.Pop(); ' – Jimmy

ответ

4

Хороший вопрос! Хорошо, что у вас уже есть работоспособное решение и вы пытаетесь улучшить его.

Вы все еще можете использовать оператор switch, но сначала вам нужно проверить, что ваш стек не пуст, прежде чем пытаться вывести следующее значение. В моей реализации я делаю эту проверку сначала, проверив stack.isEmpty() и используя условие ИЛИ || с коротким замыканием. Короткое замыкание означает, что если левая сторона условия ИЛИ истинна, то правая сторона не будет даже оценена.

Это обновленный для цикла. Я не уверен, какой класс 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; 
    } 
} 

EDIT: Я добавил отсутствующий break; заявления. Без них система выполнит несколько условий case:, потому что они будут «проваливаться» по каждому из них.

РЕДАКТИРОВАТЬ 2: Цзонг Чжэн Ли отлично подходит в своем ответе. Вы должны проверить, нет ли оставшихся символов в стеке, когда вы закончите. После вашего цикла, вы должны иметь что-то вроде этого:

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

EDIT 3: Измененный stack.firstElement() к stack.peek().

+0

@ 5gon12eder Спасибо! Неплохо подмечено. Я починил это. –

+0

Это выглядит как-то изумленно! Однако да. Я создал собственный класс, где я инициализировал мои собственные методы Push, Pop, Peek и Count. Который оставляет нас в том, что у меня нет метода isEmpty. Но я думаю, что это почти так же, как мой метод Count(), поскольку он возвращает элементы в count. так что если я что-то поменяю на него, разве это поможет? – Thrillofit123

+0

@ Thillofit123 Да, вы можете использовать свой метод Count(), если хотите, и просто выполните проверку равенства с нулем, например. 'stack.Count() == 0'. Вы должны подумать о создании собственного 'isEmpty()', хотя, потому что он сделает ваш код более приятным для чтения (плюс это просто хорошая практика, чтобы не повторять себя). –

2

Помимо проверки, соответствуют ли конкретные символы вверх, есть два случая, когда вам нужна информация о самом стеке:

  1. Когда количество скобок не очень велико в промежуточном состоянии. Это происходит, когда вы пытаетесь всплывать, когда стек пуст.

  2. Если в конце строки есть осиротевшие скобки. В этом случае стоп заканчивается непустым.

Чтобы исправить 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, в конце вашей программы, вы должны проверить стек is пустой. Это улавливает случай (bal)ler), который не был адресован.

if (!stack.empty()) 
    System.out.println(" Syntax ERROR"); 
} 
2

Вы сказали, что хотите узнать, как использовать инструкцию switch. Существует ловкий трюк вы можете использовать, называется проваливаясь:

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

Также вы можете использовать заранее реализованный Stack класс, который также generic.

+1

Это выглядит очень красиво! Я создал собственный класс, где я инициализировал мои собственные методы Push, Pop, Peek и Count. Который оставляет нас в том, что у меня нет метода isEmpty. Но я думаю, что это почти так же, как мой метод Count(), поскольку он возвращает элементы в count. так что если я что-то поменяю на него, разве это поможет? Потому что если я импортирую стек Java. Это даст мне ошибку для других вещей, так как я создал свой собственный класс с Pop, Push и так далее. – Thrillofit123

+0

Совершенно прекрасно использовать свой собственный класс 'Stack', если вы не планируете публиковать свой код в качестве библиотеки и использовать свой собственный' Stack' в его API. Вы можете проверить, пуст ли ваш стек пустым 'stack.count() == 0', поэтому вам не нужно создавать метод' isEmpty() ', который полностью зависит от вас. – kajacx

+0

Yay это сработало! Wohooo! В самом деле! Я действительно ценю ваше время здесь Kajacx и всех остальных! Это работает, насколько я вижу. Теперь я попытаюсь сделать его более прохладным, но, как я вижу сейчас. все становится хорошо! У меня нет слов, чтобы сказать !!!! – Thrillofit123

Смежные вопросы