美好的一天,我只是想知道是否有办法将一串算术表达式分段为:
-2+-3+(4+5)
进入预期结果
-2 + -3 + ( 4 + 5 )
这个给定的字符串是使用空格分段的,我打算以这种方式格式化这个表达式,因为我必须用白色空格分隔它来做其他事情。这不是我现在所关注的,我的目标是当我遇到像上面例子那样的有符号数字而不是-2 + -3 + ( 4 + 5 )
时,它看起来像- 2 + - 3 + ( 4 + 5 )
。
已经知道是什么造成了这个因为我用
替换所有标志<whitespace> <operator> <whitespace>
但是如何排除有符号数字不像预期结果那样分段?
注意: 计划与语言无关,因为截至目前,我不知道使用哪一个,算法更重要,但为了更好地理解,Java会做。
答案 0 :(得分:0)
通常这个任务是通过基于所谓的finite state machine的词法解析器来解决的。
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
}
答案 1 :(得分:0)
简单的解决方案是注意-
只有在它看起来像值的情况下才是二元运算符,在你的情况下是一个数字或)
。因此,如果您迭代令牌(其中令牌是操作员角色或一系列数字),并且只记得最后一个令牌是否为值(数字或)
),您可以随时决定是否在当前令牌之后放置一个空格。 (您还可以捕获一些语法错误。)