2012-01-09 12 views
5

電卓の入力を分割しようとしています。 たとえば、ユーザが「23 + 45 *(1 + 1)」を入力した場合、 と入力します。これを[23、+、45、*、(、1、+、1、)]に分割します。電卓の入力文字列を分割する

答えて

7

あなたの探しているものはレクサーと呼ばれます。 A レクサーは、読むことができるチャンク(トークンと呼ばれる)に入力を分割します。

あなたのレクサーはかなりシンプルで手書きで書くことができます。より複雑なレクサーの場合はflex(Adobe Flexではなく「The Fast Lexical Analyzer」のように)または(Javaを使用しているので)ANTLRを使用できます(ANTLRは単なるレクサーではありません)。

入力するトークンが単純なので、このリストを削除してすべてを1つの正規表現にマージすることができます(正規表現のリストを用意するだけです)。より高度なレクサー、それは各トークンに対して1つの正規表現を行うのに役立ちます)解析されるより多くの文字がある一方で、あなたの正規表現のそれぞれを通過し、文字列の先頭に対してそれらを一致させる試み:

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

その後、ループを開始します。一致する場合は、最初に一致したグループを入力リストに追加します。それ以外の場合は、マッチングを続行します(一致するものがない場合は、ユーザーに構文エラーがあることを伝えます)。

擬似コード:

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

実装ノート:

  • あなたの正規表現のすべてに^文字を付加することもできます。これにより、文字列の先頭にマッチを固定することができます。私の擬似コードはあなたがこれをしたことを前提としています。
0

私はまだ学んでいますが、これは文字列に分割しているので、これはちょっとうんざりかもしれません。

パブリッククラスTestClassを{

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

私はオペランドと演算子を分割し、式を評価するスタックを使用することがより適切であろうと思います。計算機では、一般に中符号表記を使用して算術式を定義します。

Operand1 op Operand2 

多くの場合に使用されるShunting-yard algorithmを調べて、数式を解析します。 Thisも読みやすいです。

関連する問題