和/或二叉树 - 根据要求拆分树

时间:2015-10-13 03:40:22

标签: c# algorithm binary-tree logical-operators

我最近试图找出一种能够优化和/或二叉树的算法,遵循一些特殊规则,我真的无法弄明白。因此,我希望你们中的一些人可能已经遇到过这样的问题。

这些问题有一些信息:

  • 树将用于在服务器上发出请求。
  • 有两种叶子:数据和价格。
  • 价格持有货币信息。
  • 在同一个请求中,两个数据之间不能存在OR。
  • 在同一个请求中,两个不同货币的价格之间不能存在OR。
  • 在同一个请求中,同一货币的两个价格之间不能存在AND。

它可能很模糊,所以有一个例子:

实施例

enter image description here

结果

enter image description here

灰色部分是软件对请求结果的处理方式。

我试图自己编写代码......但要么是无限期地继续进行,要么它没有做到它应该做的事情,它正在崩溃......或者同时它们中的三个! / p>

提前感谢您的帮助。

修改:请求必须尽可能大。我不能单独发送每个叶子,否则服务器会返回错误,因为结果太多。

我做了一些代码......但要小心,它完全凌乱。

                    //Datas yet in the tree  //or/and to add at top  //The left part to add //The right part to add
    public Tuple<Tuple<List<ExpressionAnalyzer.Data>, string>, Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>> DivideRequest(ExpressionAnalyzer.Element element)
    {
        switch (element.elementKind)
        {
            case "data":
                ExpressionAnalyzer.Data data = (element as ExpressionAnalyzer.Data);
                data.elementValide = true;
                return new Tuple<Tuple<List<ExpressionAnalyzer.Data>, string>, Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>>
                      (new Tuple<List<ExpressionAnalyzer.Data>, string>(new List<ExpressionAnalyzer.Data> { data }, ""), 
                       new Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>( data, null ));
            case "and":
                #region and
                ExpressionAnalyzer.And and = (element as ExpressionAnalyzer.And);
                Tuple<Tuple<List<ExpressionAnalyzer.Data>, string>, Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>> andResult1 = DivideRequest(and.tuple.Item1);
                Tuple<Tuple<List<ExpressionAnalyzer.Data>, string>, Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>> andResult2 = DivideRequest(and.tuple.Item2);

                if (andResult1.Item1.Item2 != "")
                {
                    ExpressionAnalyzer.And andRetour1 = new ExpressionAnalyzer.And();
                    ExpressionAnalyzer.And andRetour2 = new ExpressionAnalyzer.And();

                    andRetour1.tuple = new Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>(andResult1.Item2.Item1, and.tuple.Item2);
                    andRetour2.tuple = new Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>(andResult1.Item2.Item2, and.tuple.Item2);

                    return new Tuple<Tuple<List<ExpressionAnalyzer.Data>, string>, Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>>
                          (new Tuple<List<ExpressionAnalyzer.Data>, string>(null, andResult1.Item1.Item2), 
                           new Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>(andRetour1, andRetour2));
                }
                else if(andResult2.Item1.Item2 != "")
                {
                    ExpressionAnalyzer.And andRetour1 = new ExpressionAnalyzer.And();
                    ExpressionAnalyzer.And andRetour2 = new ExpressionAnalyzer.And();

                    andRetour1.tuple = new Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>(and.tuple.Item1, andResult2.Item2.Item1);
                    andRetour2.tuple = new Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>(and.tuple.Item1, andResult2.Item2.Item2);

                    return new Tuple<Tuple<List<ExpressionAnalyzer.Data>, string>, Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>>
                          (new Tuple<List<ExpressionAnalyzer.Data>, string>(null, andResult2.Item1.Item2),
                           new Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>(andRetour1, andRetour2));
                }

                foreach (ExpressionAnalyzer.Data andData1 in andResult1.Item1.Item1)
                foreach (ExpressionAnalyzer.Data andData2 in andResult2.Item1.Item1)
                    if (andData1.type == "Price" && andData2.type == "Price" && andData1.currency == andData2.currency)
                    {
                        return new Tuple<Tuple<List<ExpressionAnalyzer.Data>, string>, Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>>
                              (new Tuple<List<ExpressionAnalyzer.Data>, string>(null, "and"),
                               new Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>(and.tuple.Item1, and.tuple.Item2));
                    }

                List<ExpressionAnalyzer.Data> andRetourDatas = andResult1.Item1.Item1;
                andRetourDatas.AddRange(andResult2.Item1.Item1);
                return new Tuple<Tuple<List<ExpressionAnalyzer.Data>, string>, Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>>
                            (new Tuple<List<ExpressionAnalyzer.Data>, string>(andRetourDatas, ""),
                            new Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>(and, null));
                #endregion
            case "or":
                #region or
                ExpressionAnalyzer.Or or = (element as ExpressionAnalyzer.Or);
                Tuple<Tuple<List<ExpressionAnalyzer.Data>, string>, Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>> orResult1 = DivideRequest(or.tuple.Item1);
                Tuple<Tuple<List<ExpressionAnalyzer.Data>, string>, Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>> orResult2 = DivideRequest(or.tuple.Item2);

                if (orResult1.Item1.Item2 != "")
                {
                    ExpressionAnalyzer.Or orRetour1 = new ExpressionAnalyzer.Or();
                    ExpressionAnalyzer.Or orRetour2 = new ExpressionAnalyzer.Or();

                    orRetour1.tuple = new Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>(orResult1.Item2.Item1, or.tuple.Item2);
                    orRetour2.tuple = new Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>(orResult1.Item2.Item2, or.tuple.Item2);

                    return new Tuple<Tuple<List<ExpressionAnalyzer.Data>, string>, Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>>
                          (new Tuple<List<ExpressionAnalyzer.Data>, string>(null, orResult1.Item1.Item2), 
                           new Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>(orRetour1, orRetour2));
                }
                else if(orResult2.Item1.Item2 != "")
                {
                    ExpressionAnalyzer.Or orRetour1 = new ExpressionAnalyzer.Or();
                    ExpressionAnalyzer.Or orRetour2 = new ExpressionAnalyzer.Or();

                    orRetour1.tuple = new Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>(or.tuple.Item1, orResult2.Item2.Item1);
                    orRetour2.tuple = new Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>(or.tuple.Item1, orResult2.Item2.Item2);

                    return new Tuple<Tuple<List<ExpressionAnalyzer.Data>, string>, Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>>
                          (new Tuple<List<ExpressionAnalyzer.Data>, string>(null, orResult2.Item1.Item2),
                           new Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>(orRetour1, orRetour2));
                }

                foreach (ExpressionAnalyzer.Data orData1 in orResult1.Item1.Item1)
                foreach (ExpressionAnalyzer.Data orData2 in orResult2.Item1.Item1)
                    if (orData1.type == "Data" && orData2.type == "Data")
                    {
                        return new Tuple<Tuple<List<ExpressionAnalyzer.Data>, string>, Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>>
                              (new Tuple<List<ExpressionAnalyzer.Data>, string>(null, "or"),
                               new Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>(or.tuple.Item1, or.tuple.Item2));
                    }

                List<ExpressionAnalyzer.Data> orRetourDatas = orResult1.Item1.Item1;
                orRetourDatas.AddRange(orResult2.Item1.Item1);
                return new Tuple<Tuple<List<ExpressionAnalyzer.Data>, string>, Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>>
                            (new Tuple<List<ExpressionAnalyzer.Data>, string>(orRetourDatas, ""),
                            new Tuple<ExpressionAnalyzer.Element, ExpressionAnalyzer.Element>(or, null));
                #endregion
        }
        return null;     
    }

元素是由和,或和数据所代表的类。并且或者有一个元组:左右两边。

0 个答案:

没有答案