2012-01-09 26 views
5

Hesap makinesi için kullanıcı tarafından verilen girdiyi bölmeye çalışıyorum. Örneğin, kullanıcı "23 + 45 * (1 + 1)" girdiyse "Bunu [23, +, 45, *, (, 1, +, 1,)] olarak bölmek istiyorum.Hesap makinesi için bölme giriş dizesi

cevap

7

Aramanız için lexer adı verilir. Bir lexer girişi, okuyabileceğiniz parçalara (jetonları olarak adlandırılır) ayırır.

Neyse ki, yazıcınız oldukça basit ve elle yazılabilir. Daha karmaşık sözcükler için, flex (Adobe Flex değil "Hızlı Lexical Analyzer'da olduğu gibi) veya (Java kullandığınız için) ANTLR (not, ANTLR, yalnızca bir lexer'dan çok daha fazlasıdır).

Her bir belirteci eşleştirmek için normal ifadelerin bir listesi ile gelmeniz yeterlidir (girişiniz çok basit olduğundan, muhtemelen bu listeden çıkıp hepsini tek bir regexte birleştirebileceğinize dikkat edin. Daha gelişmiş sözcükler, her bir simge için bir düzenli ifadenin yapılmasına yardımcı olur. ayrıştırılmasına daha fazla karakter varken, düzenli ifadelerin her geçmesi ve dizenin başından karşı onları eşleştirmeye çalışır:

\d+ 
\+ 
- 
* 
/
\(
\) 

Sonra bir döngü başlar. Eşleşirse, ilk eşleşen grubu giriş listenize ekleyin. Aksi halde, eşlemeye devam et (bunlardan hiçbiri eşleşmezse, kullanıcıya sözdizimi hatası verdiğini söyleyin).

yalancı kod:

List<String>input = new LinkedList<String>(); 
while(userInputString.length()>0){ 
    for (final Pattern p : myRegexes){ 
     final Matcher m = p.matcher(userInputString); 
     if(m.find()) { 
      input.add(m.group()); 
      //Remove the token we found from the user's input string so that we 
      //can match the rest of the string against our regular expressions. 
      userInputString=userInputString.substring(m.group().length()); 
      break; 
     } 
    } 
} 

Uygulama notlar:

  • Sen normal ifadelerin tümüne ^ karakteri prepend isteyebilirsiniz. Bu, maçlarınızı dizinin başlangıcına sabitlemenizi sağlar. Psödo kodum bunu yaptığınızı varsayar.
0

Bu biraz eğimli olabilir, çünkü hala öğreniyorum, ancak bunları dizelere bölüyor.

genel sınıf DenemeSınıfı {

public static void main(String[] args) 
{ 
    Scanner sc = new Scanner(System.in); 
    ArrayList<String> separatedInput = new ArrayList<String>(); 
    String input = ""; 

    System.out.print("Values: "); 
    input = sc.next(); 

    if (input.length() != 0) 
    { 
     boolean numberValue = true; 
     String numbers = ""; 

     for (int i = 0; i < input.length(); i++) 
     { 
      char ch = input.charAt(i); 
      String value = input.substring(i, i+1); 

      if (Character.isDigit(ch)) 
      { numberValue = true; numbers = numbers + value; } 

      if (!numberValue) 
      { separatedInput.add(numbers); separatedInput.add(value); numbers = ""; } 
      numberValue = false; 

      if (i == input.length() - 1) 
      { 
       if (Character.isDigit(ch)) 
       { separatedInput.add(numbers); } 
      } 
     } 

    } 
    System.out.println(separatedInput); 
} 

}

1

I işlenen ve operatör bölme ve sentezleme daha uygun olur değerlendirmek yığınları kullanılarak düşünüyorum. Hesap makinesinde, aritmetik ifadeyi tanımlamak için genellikle Infix notasyonu kullanırız.

Operand1 op Operand2 

Kontrol matematiksel ifadesini ayrıştırmak için bu tür birçok durumlarda kullanılan Shunting-yard algorithm. This da iyi bir okumadır.

İlgili konular