符合'|'时编辑字符串

时间:2014-02-10 14:01:41

标签: c# string algorithm

我有一个可能有点愚蠢的问题,但我无法理解。

我从.xml读取并且这不是问题,但我有一个看起来像这样的字符串:

string str = "3|+5|*4/2+8*32|+7";

我必须将它从这种状态改为 -

(3+5)*4/2+8*(32+7).

基本上有“|”时在任何+, - ,/,*之前我必须删除“|”并添加(),然后我必须计算总和女巫不再是一个问题。 我尝试分割字符串或浏览所有字符,但没有任何效果,就像我想要的那样。

我只需要从哪里开始。如果您有任何想法,我可以试试。

3|+5时,该方法应该看到|并在第一个数字之前添加开括号,如(3+5,之后必须检查数字5包含|后的操作,如果不是,则必须在5之后放置近括号,否则进行到下一个数字,当找到没有|的操作时,它必须在操作之前放置一个近括号。

2 个答案:

答案 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
相关问题