开发者

C# resolve "(true and true) or (true or false)"

开发者 https://www.devze.com 2023-03-11 05:14 出处:网络
C#: I have a string variable that looks like this: string a = \"(true and true) or (true or false)\";

C#: I have a string variable that looks like this:

 string a = "(true and true) or (true or false)";

This can开发者_如何学编程 be anything, it can get more complex, like:

 string b = "((true and false) or (true or false) and not (true and false)) and false";

All i know is that it is correct. Cannot happen that this expression cannot be "evaluated".

Is there a way that I can somehow evaluate this? I would only like to know the outcome (result) of that string. This means I need "true" or "false" instead of this string.

I think I can make a parse method that does this, reducing the string step by step, until we got the final value, but I was wondering if there is a better approach.


Expanding on Rob's comment, you can use runtime compilation in conjunction with C# 4.0 dynamic support and do something like this:

var expression = "(true and false) or (true or false)";

var helper = "" + 
    "using System; " + 
    "public class Expression {{ public bool Eval() {{ return {0}; }} }}";

var replaced = expression.Replace("and", "&&").Replace("or", "||");

var references = new string[] { "System.dll" };
var parameters = new CompilerParameters(references, "Test.dll");
var compiler = new CSharpCodeProvider();


var results = compiler.CompileAssemblyFromSource(
    parameters, 
    String.Format(helper, replaced));

dynamic exp = Activator.CreateInstance(
    results.CompiledAssembly.GetType("Expression"));

Console.WriteLine(exp.Eval());


Something like this maybe?

string previous = string.Empty;
while (b != previous) 
{
     previous = b;
     b = b.Replace("true and false", "false");
     b = b.Replace("true and true", "true");
     b = b.Replace("false and true", "false");
     b = b.Replace("false and false", "false");
     b = b.Replace("false or false", "false");
     b = b.Replace("true or false", "true");
     b = b.Replace("true or true", "true");
     b = b.Replace("false or true", "true");
     b = b.Replace("(false)", "false");
     b = b.Replace("(true)", "true");
     b = b.Replace("not false", "true");
     b = b.Replace("not true", "false");
 }

Note that the specification allows ambigious formulations, such as these:

"false and false or true"
"false and true or true"

Both of these expressions are "true" if the and is evaluted first, and "false" if the or is evaluated first. Therefore, requireing parenthesis at every level would be better. Requiring left-to-right evaluation is another option, but that makes the code a bit more complex.

For those of you who may object to this style of solution for this style of problem, remember that some mathematicians believe that all of mathematics may be reduced to this sort of symbol manipulation. It is said that one of the main criticisms of Russell and Whitehead’s Principia Mathematica is that it embues the formulas with too much meaning.


Parsing is your best bet. If you have to check for typos, that would make it a bit harder.


C# Doesn't have an Eval method or something similar that would allow you to just run a statement like this to gain the final resultant. Unless I'm missing something, you'll have to parse through and reduce that way.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号