我有一个可能有点愚蠢的问题,但我无法理解。
我从.xml读取并且这不是问题,但我有一个看起来像这样的字符串:
string str = "3|+5|*4/2+8*32|+7";
我必须将它从这种状态改为 -
(3+5)*4/2+8*(32+7).
基本上有“|”时在任何+, - ,/,*之前我必须删除“|”并添加(),然后我必须计算总和女巫不再是一个问题。 我尝试分割字符串或浏览所有字符,但没有任何效果,就像我想要的那样。
我只需要从哪里开始。如果您有任何想法,我可以试试。
当3|+5
时,该方法应该看到|并在第一个数字之前添加开括号,如(3+5
,之后必须检查数字5包含|
后的操作,如果不是,则必须在5之后放置近括号,否则进行到下一个数字,当找到没有|
的操作时,它必须在操作之前放置一个近括号。
答案 0 :(得分:1)
此解决方案的前提条件是输入表达式永远不会有括号。如果输入有它们,那么这不是解决方案,需要一些其他解决方案。
将输入字符串分解为标记列表:
string expression = "3|+5|*4/2+8*32|+7";
List<string> tokens = TokenizeExpression(expression); // You code this
内容应为{ "3", "|+", "5", "|*", "4", "/", "2", "+", "8", "*", "32", "|+", "7" }
。现在,为每个"|op"
运算符创建一个新列表,其中元素"exp1", "|op", "exp2"
将替换为单个字符串"(exp1 op exp2)"
。从开始到结束,或者换句话说从左到右。迭代应该是这样的:
{ "(3+5)", "|*", "4", "/", "2", "+", "8", "*", "32", "|+", "7" }
{ "((3+5)*4)", "/", "2", "+", "8", "*", "32", "|+", "7" }
{ "((3+5)*4)", "/", "2", "+", "8", "*", "(32+7)" }
重复直到替换所有"|op"
个运算符。
结果是列表中所有元素的连接,即:"((3+5)*4)/2+8*(32+7)"
。
答案 1 :(得分:1)
这是一种适合您输入的方法。但我担心有很多方法可能会失败。也许它无论如何都会给你一个想法:
string str = "3|+5|*4/2+8*32|+7";
char[] operators = {'+', '-', '/', '*'};
StringBuilder sb = new StringBuilder();
int index = str.IndexOf('|');
if (index > 0)
{
for (int i = 0; i < str.Length; i++)
{
Char c = str[i];
if (c != '|')
{
sb.Append(c);
continue;
}
Char nextChar = str[i + 1];
if (operators.Contains(nextChar))
{
// next char is operator, find index before last number
int countLeft = 1;
while (i - ++countLeft > 0 && Char.IsDigit(str[i - countLeft]))
;
int countRight = 2; // skip operator
while (i + ++countRight < str.Length && Char.IsDigit(str[i + countRight]))
;
countLeft--;
countRight--;
int start = i - countLeft;
string numLeft = str.Substring(start, countLeft);
string numRight = str.Substring(i + 2, countRight - 1);
sb.Remove(start, countLeft);
string expr = string.Format("({0}{1}{2})", numLeft, nextChar, numRight);
sb.Append(expr);
i = i + countRight + 1;
}
}
}
else
sb.Append(str);
使用DataTable.Compute
- 技巧:
DataTable calculator = new DataTable();
object value = calculator.Compute(sb.ToString(), null);
double result = System.Convert.ToDouble(value); // 328.0