2013-10-13 51 views
0

我正在编写一个分隔符检查程序。当用户如检查字符是否匹配可接受字符列表

12+{2*[3*(24+45)+5]} 

我需要检查是否分隔符匹配输入公式(有点像什么我们表达了java编译器检查)。

我知道这可以用一吨的if/else if语句来完成,但我记得使用正则表达式的字符串,例如:

if(s.matches("[abc]+") 
System.out.print(s); 

但是,这并不对人物的工作。如果我可以写出类似于上面的表达式:

for(byte i = 0; i < aString.length(); i++) 
{ 
    if(aString.charAt(i).matches("[({[]})]+") // maybe '[]' is a problem 
    stack.push(aString.charAt(i)); 
} 

这样的方法是否适用于字符?我能做什么?

+0

我认为这是一个错误的路要走。它可能变得强大丑陋。例如,你将如何处理''[3 +(2 * 4])“'? –

+0

我只需要知道特定字符是否可以接受。如果是 - 使用另一种算法 - 我会检查它是否与前一个匹配;如果没有,则会抛出异常。所以这个检查过程会跳过字母,数字,算术运算符等。 –

+0

啊所以这个算法不会在意分隔符的排序吗? –

回答

2

我想说一个解决方案是使用Stack并重新开始每个输入字符串。

  1. 当打开托架{, [, (被发现,它压入堆栈。
  2. 当发现一个闭括号}, ],)时,pop它从堆栈中。
  3. 使用if语句比较,看看你是否有匹配。如果你不这样做,请返回false

当你与你的搜索完成后,检查是否有一个空栈,要么返回truefalse

Stack Example: Delimiter Matching

使用堆栈将只返回false的这个例子,如果你缺少一个分隔符比赛。

import java.util.Stack; 

class BracketChecker { 
    private String input; 

    public BracketChecker(String in) { 
    input = in; 
    } 

    public void check() { 
    Stack<Character> theStack = new Stack<Character>(); 

    for (int j = 0; j < input.length(); j++) { 
     char ch = input.charAt(j); 
     switch (ch) { 
     case '{': 
     case '[': 
     case '(': 
     theStack.push(ch); 
     break; 
     case '}': 
     case ']': 
     case ')': 
     if (!theStack.isEmpty()) { 
      char chx = theStack.pop(); 
      if ((ch == '}' && chx != '{') || 
       (ch == ']' && chx != '[') || 
       (ch == ')' && chx != '(')) 
       System.out.println("Error: " + ch + " at " + j); 
      } else 
       System.out.println("Error: " + ch + " at " + j); 
       break; 
       default: 
       break; 
      } 
    } 
    if (!theStack.isEmpty()){ 
     System.out.println("Error: missing right delimiter"); 
    } 
    } 
} 

class delimTest { 
    public static void main(String[] args) { 

    String input = "12+{2*[3*(24+45)+5}"; 

    BracketChecker theChecker = new BracketChecker(input); 
    theChecker.check(); 
    } 
} 
+0

这正是我的程序所做的事情,遇到它时会压入开始分隔符,并在遇到计数器部分时弹出它。我的困境是如何尽可能有效地识别它们。看起来你有这方面的经验,希望你知道一个方法。无论哪种方式,谢谢! (: –

+0

这和我在做的事情没有什么不同,但是你实现它的方式是例外的,我不知道java有一个内置的堆栈结构,现在我知道了。 –

2

可以保持List<Character>持有“分隔符”字,然后在字符串中的每个字符运行list.contains(),以确定它是否是一个有效的分隔符 - 这会是一个很多比正则表达式为你的任务更好的性能。不过,您可能想重新考虑使用byte作为循环变量循环使用String;这可能并不总是适合你。对于一个简单的字符串(在BMP之外没有花哨的Unicode字符),您可以使用for (char ch : aString.toCharArray()) {...}对其进行循环。

+0

听起来好像它可以工作,不幸的是我不知道如何实现列表。所以这超出了我的能力。至于字节,我认为这将足够,因为我将强制执行最大长度为100个字符。让我知道是否有其他一些后果,我可能忽略。谢谢! (: –

+0

)在这种情况下,我可能会推荐编写一个单独的方法,它将一个字符作为输入并返回一个布尔值,表示输入的char是否是分隔符。只需在循环中的每个字符上运行它,而不是混淆(提示:考虑如何使用||运算符来实现'isDelimiter()')。 – Josh

+0

是的,我意识到这个选项,我希望Java语言功能会让我绕过那个选择哦,好吧,我想我不能指望所有的东西都很简单,谢谢! –

相关问题