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 回答