Необходимо руководство по созданию дерева оценочной логической логики

StackOverflow https://stackoverflow.com/questions/1830925

Вопрос

Кажется, я не могу найти указатель в правильном направлении, я даже не уверен, какие термины мне следует исследовать, но бесчисленные часы поиска в Google, кажется, кружат меня по кругу, так что, надеюсь, коллективный улей интеллекта Стека Переполнение может помочь.

Проблема в том, что мне нужен способ фильтровать данные в том, что я могу назвать только составным логическим деревом.В настоящее время система реализует простую систему фильтрации AND.Например, предположим, что у нас есть набор данных о людях.Вы добавляете несколько фильтров, которые показывают всех людей, где (Пол = Женский) И (Возраст > 23) И (Возраст < 30) И ( Статус = Одинокий).Достаточно просто: перебирать каждый элемент, добавлять в допустимую коллекцию элементов только в том случае, если каждое условие истинно.

Проблема, с которой я сталкиваюсь, заключается в том, как мне поступить с тем, чтобы пользователь мог создавать сложные запросы, а также и/или?Я имею в виду что-то вроде дерева, где каждый узел представляет собой выражение, оценивающее его дочерние элементы как истинное или ложное.Упрощенным примером может быть фильтрация вниз до ((Пол == Мужской И Возраст == 25) ИЛИ (Пол == Женский И Статус == Одинок)) И IQ > 120.К сожалению, на данный момент я не могу придумать лучшего примера.Но как бы вы представляли этот тип дерева выражений и оценивали элементы коллекции по этим фильтрам?Какие ссылки могут помочь?Черт, какие чертовы поисковые запросы в Google могут привести в положительном направлении?!

Спасибо всем, кто может оказать любую помощь.

Вот пример составного запроса в древовидной форме с использованием набора данных о людях.

  • Запрос. Покажите мне всех людей, у которых пол мужской и глаза зеленые, пол женский, глаза голубые или статус одинок.В паренной форме (пол == мужчина && eye == зеленый) || (Sex == kener && (eye == blue || status == сингл)))

Итак, в древовидной форме я думаю

o-Root Node
  - And - Sex = Male
     - And - Eyes = Blue
  - Or - Sex = Female
     - And Eyes = Blue
     - Or Status = Single

Я считаю, что решение состоит в том, чтобы представить каждый узел в такой структуре данных, как

Node
{
   OpType - AND or OR
   ExpressionField - The field to evaluate
   ExpressionOp -   =, !=, >, >=, <, <=
   ExpressionValue - the value to compare the field's value against

   Function Evaluate() - returns a bool
}

Итак, для данного узла оцените детей, если вы являетесь узлом И, затем верните true, если ваше выражение дает значение true, и все ваши дочерние элементы AND оцениваются как true или любой дочерний элемент OR оценивается как true и выполняется рекурсия вверх.

Кажется, он удовлетворяет всем концептуальным условиям, которые я могу ему предложить, но мы это сделаем, как только я его реализую.Я опубликую реальный код позже, когда он заработает, и фотографии, которые помогут лучше описать эту проблему другим.

Это было полезно?

Решение

Ваш анализ выражения ((Пол == Мужской И Возраст == 25) OR (Пол == Женский И Статус == Одинок)) AND IQ > 120 выглядит странно.Я бы разобрал это как:

* And
    * Or
        * And
            * ==
                * Sex
                * Male
            * ==
                * Eyes
                * Blue
        * And
            * ==
                * Sex
                * Female
            * ==
                * Status
                * Single
    * >
        * IQ
        * 120

Тип дерева будет:

Node
{
    bool evaluate ()
}

AndNode : Node
{
    Node left
    Node right

    bool evaluate ()
    {
        return left.evaluate () && right.evaluate ()
    }
}

// OrNode is similar

EqualsNode : Node
{
    Field field
    Value value

    bool evaluate ()
    {
        return field.value () == value
    }
}

// Likewise for <, >, etc

Другие советы

Запросы такого типа часто представляются как ORредактор массива ANDстатьи изд.То есть табличный формат, в котором вы читаете несколько условий. ANDпрочитали вместе, а затем прочитали до OR их.Это приводит к некоторому повторению условий, но пользователям легко читать, писать и понимать.Ваш образец ((Sex == Male AND Age == 25) OR (Sex == Female AND Status == Single)) AND IQ > 120 будет выглядеть как

Sex == Male   & Age == 25        & IQ > 120 
Sex == Female & Status == Single & IQ > 120 

Возможно, вам захочется поискать в Google такие термины, как «исчисление предикатов» и «конъюнктивная нормальная форма».

Я должен сказать, что именно для этого создаются механизмы баз данных.Вы можете делать все, что вам нужно, с помощью заданной логики, и даже можете получить желаемый результат, но это стандартные проблемы, решаемые базами данных и SQL.Вы также можете посмотреть linq для решения в коде.

Похоже, вам нужно создать пользовательский интерфейс, позволяющий создавать простое дерево разбора.Когда вы нажмете GO, вы сможете пройтись по дереву и создать дерево выражений LINQ из этой структуры пользовательского интерфейса.Выполните запрос LINQ, а затем обработайте результаты по мере необходимости.Поэтому я бы рекомендовал вам прочитать о деревьях выражений LINQ.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top