2015-09-05 99 views
1

我不知道给这个问题提供了什么标题。请改变它,如果你想出以下说明什么好和相对的:通过检查同一列表中的元素来更改列表元素

我有一些数学运算中像一个列表:

A=11 
B=1+2 
C=A+E 
D=B+A 
E=C+B 

但你可以看到有在循环引用问题C=A+EE=C+B。要报告此类问题,我的计算器应用程序将用<CIR_REF>替换循环引用。这将导致:

A=11 
B=1+2 
C=A+<CIR_REF> 
D=B+A 
E=<CIR_REF>+B 

我无法为此形成逻辑。最近的逻辑,我能够达到是继但它并不甚至似乎非常优化的解决方案,我不认为它会得到期望的结果:

class Expression { 
    public char ID; //Like A,B,C,D (operand representing this expression) 
    public string value; //Contains the actual expression 
} 
List<Expression> expressions; //assigned outside the class containing this whole code. 
public void ResolveCircularReference() { 
    for (int i = 0; i < expressions.Count; i++) { 
     List<string> Ops = Utility.GetOperands(expressions[i].value); 
     if (Ops.Count > 0) { 
      for (int j = 0; j < expressions.Count; j++) { 
       if (Ops.Contains(expressions[j].ID.ToString())) { 
        expressions[j].value = expressions[j].value.Replace(expressions[j].ID, "<CIR_REF>"); 
       } 
      } 
     } 
    } 
} 

那么,有没有其他优化的方式来此使用LINQ或LAMBDA表达式甚至标准循环?

+3

你的问题等同于一个有向图中寻找圆。首先看看谷歌:https://www.google.com/search?q=finding%20circles%20in%20a%20directed%20graph –

回答

2

你可以这样做:

扩展您Expression类,添加两个另一个IsCyclic & ConnectedBy性能

public class Expression 
{ 
    public char Id { get; set; } 
    public string Value { get; set; } 
    public bool IsCyclic { get; set; } 
    public char ConnectedBy { get; set; } 
} 

方法来获得操作数:

private static IEnumerable<string> GetOperands(string value) 
{ 
    return Regex.Split(value, "[-+*/]"); 
} 

获取的输入值:

var expressions = new List<Expression> 
{ 
    new Expression{Id = 'A', Value = "11"}, 
    new Expression{Id = 'B', Value = "1+2"}, 
    new Expression{Id = 'C', Value = "A+E"}, 
    new Expression{Id = 'D', Value = "B+A"}, 
    new Expression{Id = 'E', Value = "C+B"} 
}; 

现在,检测表达式,如果他们是循环并通过其标识它们连接的是:

foreach (var expression in expressions) 
{ 
    var operands = GetOperands(expression.Value); 
    var localCopy = expression; 
    foreach (var operand in 
     from operand in operands 
     from expression1 in expressions 
     where operand == expression1.Id.ToString() 
     && expression1.Value.Contains(localCopy.Id) 
     select operand) 
     { 
      expression.IsCyclic = true; 
      expression.ConnectedBy = operand[0]; 
     } 
} 

现在,"<CIR_REF>"

foreach (var expression in expressions.Where(expression => expression.IsCyclic)) 
{ 
    expression.Value = expression.Value.Replace(expression.ConnectedBy.ToString(), "<CIR_REF>"); 
} 

这就是它与ConnectedBy替换特定的值。

输出:

enter image description here

+0

非常感谢。你救了我的命。 :) –

+0

完成:) –