在C#中将Text转换为布尔表达式

时间:2016-04-09 18:36:40

标签: c#

我有一个项目为信息检索系统创建一个布尔表(关联矩阵),所以我创建了3个文件,我从每个文件中取出单词并从中删除了停止的单词,并使用它们将它们添加到listView中c#语言,我需要的是能够从textBox中获取查询并将其转换为合适的布尔表达式,以便它返回满足布尔表达式的文档的名称。 例如。 “艾哈迈德,爱,而不是阿里” 这应该给我Ahmed&&爱与& amp; !对于doc1来说,阿里是真的。

enter image description here

2 个答案:

答案 0 :(得分:2)

使用String.Replace

    string src = "Ahmed and love and not ali";
    string res = src.Replace("and", "&&")
                    .Replace("not", "!");
    string[] parts = res.Split(' '); // { Ahmed , && , love , && , ! , ali }

    //Do Shunting-Yard algorithm to convert infix expression to postfix
    ToPostfix(parts); // Ahmed love && ali ! &&
    bool result = PerformRPN(parts); //Calculate postfix, you should read the Reverse Polish Notation article

链接到wiki(更新了shunting-yard参考OP问题的更接近的版本):
Shunting-Yard algorithm
Reverse Polish Notation

算法中有一些关键概念我将进一步解释

  • IsOperator
  

bool IsOperator(字符串部分){return part ==“&&” ||部分== “||” || part ==“!” || ...}

  • IsOperand - 不是运营商

如果您需要帮助,请告诉我

额外:(正如Jared建议的那样)
您应该在字典中初始化表值

Dictionary<string, bool> doc1 = new Dictionary<string, bool>();
doc1.Add("Ahmed", doc1BooleanArray[0]);
doc1.Add("love", doc1BooleanArray[1]);
...

因此,当您需要获取操作数值来计算表达式时,只需使用:

//Get operand_part = "Ahmed"
bool val = doc1[operand_part]

答案 1 :(得分:0)

我能想到的最简单的事情是使用DataTable

这应该处理所有&#34;快乐路径&#34;正确。就像它在评论中所说的那样,您可能需要进行额外的验证,以明确错误地将您认为无效的输入错误。

class Program
{
    static void Main(string[] args)
    {
        // Unit test the EvaluateBinaryExpression method.
        Console.Out.WriteLine(EvaluateBinaryExpression("true")); // true
        Console.Out.WriteLine(EvaluateBinaryExpression("false")); // false
        Console.Out.WriteLine(EvaluateBinaryExpression("true or false")); // true
        Console.Out.WriteLine(EvaluateBinaryExpression("false or false")); // false
        Console.Out.WriteLine(EvaluateBinaryExpression("true and false")); // false
        Console.Out.WriteLine(EvaluateBinaryExpression("true and true")); // true
        Console.Out.WriteLine(EvaluateBinaryExpression("true and not false")); // false

        //
        // This should give me Ahmed && love && ! Ali which will be true for doc1.

        // TODO: get these values out of the table.
        var doc1Results = new Dictionary<string, bool>()
        {
            { "Ahmed", true },
            { "love", true },
            { "ali", false }
        };

        // Then just call it like this
        Console.Out.WriteLine(EvaluateResults("Ahmed and love and not ali", doc1Results)); // true
    }

    public static bool EvaluateResults(string expression, IDictionary<string, bool> results)
    {
        // TODO validate input expression and results

        // Make sure the expression is padded with whitespace for replacing.
        var replaced = " " + expression + " ";

        foreach (var kvp in results)
        {
            var search = " " + kvp.Key + " ";
            var replacement = " " + kvp.Value.ToString() + " ";
            // TODO make sure casing, etc. doesn't matter.
            replaced = replaced.Replace(search, replacement);
        }

        return EvaluateBinaryExpression(replaced);
    }

    public static bool EvaluateBinaryExpression(string expression)
    {
        // TODO what if this throws an error?
        var dt = new System.Data.DataTable();
        dt.Columns.Add("Test", typeof(object));
        dt.Rows.Add(new object[] { null });
        dt.Columns[0].Expression = expression;
        var value = dt.Rows[0][0] as bool?;
        return value.Value;
    }
}