1

こんにちは、次のような算術式の文字列を断片化する方法があるかどうか疑問に思っていました。

-2+-3+(4+5)

期待される結果

-2 + -3 + ( 4 + 5 )

この指定された文字列は空白を使用して断片化されています。空白で区切られた何か他のことをしなければならないので、この式をこのようにフォーマットするつもりです。それは私が今心配していることではありません。私が目指しているのは、上記の例のような符号付き数字に遭遇したときに、これではなく、-2 + -3 + ( 4 + 5 )このように見えること- 2 + - 3 + ( 4 + 5 )です。

すべての記号を

<whitespace> <operator> <whitespace>

しかし、期待される結果のように断片化されないように符号付き数字を除外するにはどうすればよいですか?

注: 言語に依存しないことを計画しているのは、現時点ではどちらを使用するかわからないためです。アルゴリズムの方が重要ですが、理解を深めるために、Java を使用することをお勧めします。

4

2 に答える 2

0

通常、このタスクは、いわゆる有限状態マシンに基づく字句パーサーで解決されます。

string s = "-2+-3+(4+5)";
List<string> tokens = new List<string>();
const int ST_NONE = 0, ST_MINUS = 1, ST_DIGITS = 2, ST_PUNCT = 3;
int j = 0; // token start
int st = ST_NONE; // state
for(int i = 0; i < s.Length(); ++i) {
    switch(s[i]) {
        case '0' .. '9':
            if (st != ST_NONE && st != ST_DIGITS) { // any prev token
                tokens.Add(s.SubStr(j, i - j)); // yield prev token
                j = i; // start of new token
            }
            st = ST_DIGITS; // note transition from ST_MINUS
            break;
        case '-': // special case since number can start with it
            if (st == ST_DIGITS) { // "4-" is definitely means "4 - .."
                tokens.Add(s.SubStr(j, i - j)); // yield prev number
                j = i, st = ST_PUNCT;
            }
            else if (st != ST_NONE) {
                tokens.Add(s.SubStr(j, i - j)); // yield prev token
                j = i, st = ST_MINUS;
            }
            else {
                j = i, st = ST_MINUS;
            }
            break;
        case '+': case '*': case '/': case '(': case ')':
            if (st != ST_NONE) { // any prev token
                tokens.Add(s.SubStr(j, i - j)); // yield prev token
                j = i;
            }
            st = ST_PUNCT;
            break;
        default:
            throw new UnexpectedCharacter();
    }
}
if (st != ST_NONE) { // any prev token
    tokens.Add(s.SubStr(j, i - j)); // yield prev token
}
于 2012-11-27T15:33:52.030 に答える
0

簡単な解決策は、 a が値のように見える何かに従う場合にのみ、二項演算子であることに注意すること-です。この場合、数字または a)です。したがって、トークン (トークンは演算子文字または一連の数字のいずれか) を反復処理し、最後のトークンが値 (数字または ) であったかどうかを覚えていれば、)後にスペースを入れるかどうかをいつでも決定できます。現在のトークン。(また、いくつかの構文エラーをキャッチすることもできます。)

于 2012-11-27T16:44:02.827 に答える