Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.67/18: Рейтинг темы: голосов - 18, средняя оценка - 4.67
3 / 3 / 2
Регистрация: 30.07.2017
Сообщений: 223

Алгоритм поиска по выражениям больше/меньше

23.11.2018, 13:34. Показов 4208. Ответов 53
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день!
Необходимо реализовать алгоритм поиска значения по правилам больше/меньше.
Например, есть параметр А и результирующий параметр В.
Если А меньше или равно 10, то В = 0
Если А меньше или равно 15, то В = 0,5
Если А меньше или равно 20, то В = 1
Если А меньше или равно 25, то В = 1,5
Если А больше 25, то В = 2.
Сами правила сохранены в виде таблицы в БД.
С чего начать?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.11.2018, 13:34
Ответы с готовыми решениями:

Искомое число больше 400 и меньше 500. Составить алгоритм поиска этого числа
Искомое число больше 400 и меньше 500. Составить алгоритм поиска этого числа, если сумма его цифр равна 9 и оно равняется 47/36 числа,...

RSA алгоритм. Закрытый ключ больше или меньше открытого ключа?
Товарищи, ответьте пожалуйста на вопрос. Закрытый ключ больше или меньше открытого ключа? В методичке прочитал, что закрытый больше...

Нужен алгоритм поиска пути в этом лабиринте (будь то волновой алгоритм или алгоритм правой/левой руки )
#include "stdafx.h" #include <iostream> #include <conio.h> using namespace std; void lab () { int s1 = 0; int s2 =...

53
3 / 3 / 2
Регистрация: 30.07.2017
Сообщений: 223
23.11.2018, 15:43  [ТС]
Студворк — интернет-сервис помощи студентам
Нет, последнее сработавшее правило не получится. Точнее получится, именно так я пытался сделать предварительно отсортировав, как вы выразились тут, "узловые значения" по убыванию и правила по убыванию (т.е. сначала применяются правила с больше, а потом с меньше). А если правила будут хаотичны, тогда результат не подходит
0
187 / 100 / 19
Регистрация: 15.09.2011
Сообщений: 801
23.11.2018, 15:45
Элд Хасп, в C# можно через Expression<Func<T>> задать любое правило и действие на него. снова не попал?
0
3 / 3 / 2
Регистрация: 30.07.2017
Сообщений: 223
23.11.2018, 15:48  [ТС]
umatkot, давайте попробую объяснить исходный пример еще раз.
Если значение А попадает в диапазон (-Infinity, +10], тогда результат должен быть 0
Если в диапазон (+10, +15] - 0,5
Если в диапазон (+15, +20] - 1
Если в диапазон (+20, +25] - 1,5
Если в диапазон (+25, +Infinity] - 2
Так понятнее? Извиняюсь за первоначальную неточность, надо было сразу так написать

Добавлено через 56 секунд
Короче пока вам задачу объяснял, понял примерно как её решать )))

Добавлено через 1 минуту
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Надо продумать алгоритм целиком. Допустим, а что делать со значениями не попавшими ни в один диапазон?
Такого быть не должно. Или пользователь сам виноват. Значение по умолчанию - 0.
0
187 / 100 / 19
Регистрация: 15.09.2011
Сообщений: 801
23.11.2018, 16:29
wrq2017, не ну я точно тогда дурак. а почему формула не подходит то???? дайте пример, где она не сработает

Добавлено через 20 минут
вот моя функция(пишу без студии, так как виртуалку грузить лень)
в каких случая она не работает?
https://dotnetfiddle.net/TFB1Oc
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void Main()
    {
        for(double d = - 1; d < 26; d++)
        {
            var result = Round2Fraction(d);
            Console.WriteLine(string.Format("A = {0}; B = {1}", d, result));
        }
        Console.WriteLine("Hello World");
    }
    
    
    public static double Round2Fraction(double value){
        if(value < 0) return 0;
        if(value > 25) return 2.5;
        return Math.Round((value / 10) / 0.5) * 0.5;
    }


вот что выдаёт -
Кликните здесь для просмотра всего текста
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
A = -1; B = 0
A = 0; B = 0
A = 1; B = 0
A = 2; B = 0
A = 3; B = 0.5
A = 4; B = 0.5
A = 5; B = 0.5
A = 6; B = 0.5
A = 7; B = 0.5
A = 8; B = 1
A = 9; B = 1
A = 10; B = 1
A = 11; B = 1
A = 12; B = 1
A = 13; B = 1.5
A = 14; B = 1.5
A = 15; B = 1.5
A = 16; B = 1.5
A = 17; B = 1.5
A = 18; B = 2
A = 19; B = 2
A = 20; B = 2
A = 21; B = 2
A = 22; B = 2
A = 23; B = 2.5
A = 24; B = 2.5
A = 25; B = 2.5


уже засыпаю, короче. надо сместить всё на 0,5 вправо...
0
3 / 3 / 2
Регистрация: 30.07.2017
Сообщений: 223
23.11.2018, 16:40  [ТС]
umatkot, исходные данные приведены для примера, если будет для последнего случая не 2, а 10.5? Переделывать формулу, переопределять индивидуальные случаи? Вариант с формулой НЕ катит. В любом случае, спасибо за направление мысли!

Добавлено через 4 минуты
Делаю так. Класс условий:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class RangeValue: Entity
    {
//Тип объекта
        public virtual BusinessObject BusinessObject { get; set; }
//Левая граница диапазона. Если null - то минус бесконечность
        public virtual double? MinValue { get; set; }
//Правая граница диапазона. Если null - то плюс бесконечность
        public virtual double? MaxValue { get; set; }
//Тип строгости левой/правой границ (включая/не включая границу)
        public virtual TypeOfBorderStrong TypeOfBorderStrong { get; set; }
//Результат, если искомое значение попадает в диапазон
        public virtual double BOValue { get; set; }
    }
 
//Совпадение найдено! Условие досрочного выхода из цикла
 bool Match = false;
 
                for (int i = 0; i < rangeValues.Count && !Match; i++)
                {
                    switch (rangeValues[i].TypeOfBorderStrong.Id)
                    {
                        case (int)BorderStrongTypeId.LeftExcludeRightExclude:
                            if (rangeValues[i].MinValue < temp && rangeValues[i].MaxValue > temp)
                            {
                                result = rangeValues[i].BOValue;
                                Match = true;
                            }
                            break;
                        case (int)BorderStrongTypeId.LeftExcludeRightInclude:
                            if (rangeValues[i].MinValue < temp && rangeValues[i].MaxValue >= temp)
                            {
                                result = rangeValues[i].BOValue;
                                Match = true;
                            }
                            break;
                        case (int)BorderStrongTypeId.LeftIncludeRightExclude:
                            if (rangeValues[i].MinValue <= temp && rangeValues[i].MaxValue > temp)
                            {
                                result = rangeValues[i].BOValue;
                                Match = true;
                            }
                            break;
                        case (int)BorderStrongTypeId.LeftIncludeRightInclude:
                            if (rangeValues[i].MinValue <= temp && rangeValues[i].MaxValue >= temp)
                            {
                                result = rangeValues[i].BOValue;
                                Match = true;
                            }
                            break;
                        default:
                            result = 0;
                            break;
                    }
                }
Добавлено через 38 секунд
Вот кажется уже рабочее решение... Прошу прокомментировать.
0
187 / 100 / 19
Регистрация: 15.09.2011
Сообщений: 801
23.11.2018, 16:58
данный свитч можно превратить в эквивалентного монстра
C#
1
2
3
4
5
6
7
8
9
10
if (
            (rangeValues[i].MinValue < temp && rangeValues[i].MaxValue > temp) && rangeValues[i].TypeOfBorderStrong.Id == (int)BorderStrongTypeId.LeftExcludeRightExclude||
            (rangeValues[i].MinValue < temp && rangeValues[i].MaxValue >= temp) && rangeValues[i].TypeOfBorderStrong.Id == (int)BorderStrongTypeId.LeftExcludeRightInclude||
            (rangeValues[i].MinValue <= temp && rangeValues[i].MaxValue > temp) && rangeValues[i].TypeOfBorderStrong.Id == (int)BorderStrongTypeId.LeftIncludeRightExclude||
            (rangeValues[i].MinValue <= temp && rangeValues[i].MaxValue >= temp) && rangeValues[i].TypeOfBorderStrong.Id == (int)BorderStrongTypeId.LeftIncludeRightInclude
            )
        {
            result = rangeValues[i].BOValue;
            Match = true;
        }
результат аналогичный
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
23.11.2018, 17:22
Лучший ответ Сообщение было отмечено wrq2017 как решение

Решение

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
    public enum BorderStrongTypeId
    {
        LeftExcludeRightExclude,
        LeftExcludeRightInclude,
        LeftIncludeRightExclude,
        LeftIncludeRightInclude
    }
 
    public class TypeOfBorderStrong
    {
        public BorderStrongTypeId Id { get; set; }
    }
 
    public class RangeValue// : Entity
    {
        //Тип объекта
        //public virtual BusinessObject BusinessObject { get; set; }
        //Левая граница диапазона. Если null - то минус бесконечность
        public virtual double? MinValue { get; set; }
        //Правая граница диапазона. Если null - то плюс бесконечность
        public virtual double? MaxValue { get; set; }
        //Тип строгости левой/правой границ (включая/не включая границу)
        public virtual TypeOfBorderStrong TypeOfBorderStrong { get; set; }
        //Результат, если искомое значение попадает в диапазон
        public virtual double BOValue { get; set; }
 
        public bool IsInRange(double value)
        {
            double min = MinValue ?? double.NegativeInfinity;
            double max = MaxValue ?? double.NegativeInfinity;
            switch (TypeOfBorderStrong.Id)
            {
                case BorderStrongTypeId.LeftExcludeRightExclude:
                    return min < value && max > value;
                case BorderStrongTypeId.LeftExcludeRightInclude:
                    return min < value && max >= value;
                case BorderStrongTypeId.LeftIncludeRightExclude:
                    return min <= value && max > value;
                case BorderStrongTypeId.LeftIncludeRightInclude:
                    return min <= value && max >= value;
            }
            return false;
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            var rangeValues = new List<RangeValue>
            {
                new RangeValue { MinValue = null, MaxValue = 10, BOValue = 0, TypeOfBorderStrong = new TypeOfBorderStrong { Id = BorderStrongTypeId.LeftExcludeRightExclude} },
                new RangeValue { MinValue = 10, MaxValue = 15, BOValue = 0.5, TypeOfBorderStrong = new TypeOfBorderStrong { Id = BorderStrongTypeId.LeftExcludeRightExclude} },
                new RangeValue { MinValue = 15, MaxValue = 20, BOValue = 1, TypeOfBorderStrong = new TypeOfBorderStrong { Id = BorderStrongTypeId.LeftExcludeRightExclude} },
                new RangeValue { MinValue = 20, MaxValue = 25, BOValue = 1.5, TypeOfBorderStrong = new TypeOfBorderStrong { Id = BorderStrongTypeId.LeftExcludeRightExclude} },
                new RangeValue { MinValue = 25, MaxValue = null, BOValue = 1.5, TypeOfBorderStrong = new TypeOfBorderStrong { Id = BorderStrongTypeId.LeftExcludeRightExclude} }
            };
 
            double v = 11;
 
            RangeValue rw = rangeValues.FirstOrDefault(r => r.IsInRange(v));
 
            double res = rw?.BOValue ?? 0;
 
            Console.WriteLine($"Value {res}");
 
            Console.ReadKey();
        }
    }
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
23.11.2018, 18:15
Цитата Сообщение от umatkot Посмотреть сообщение
можно через Expression<Func<T>> задать любое правило и действие на него. снова не попал?
Можно. И Мне кажется это неплохой вариант, можно попробовать ещё через делегаты.
Но блок switch...case... очень криво смотрится.
0
3 / 3 / 2
Регистрация: 30.07.2017
Сообщений: 223
23.11.2018, 21:02  [ТС]
Цитата Сообщение от Someone007 Посмотреть сообщение
double res = rw?.BOValue ?? 0;
Поясните, пожалуйста, эту строку. Есть какой-то более длинный привычный эквивалент?
Вообще, Ваш вариант является немного измененным моим последним предложением. А принципиально другие идеи есть?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
23.11.2018, 21:16
Лучший ответ Сообщение было отмечено wrq2017 как решение

Решение

Цитата Сообщение от wrq2017 Посмотреть сообщение
Вот кажется уже рабочее решение... Прошу прокомментировать.
Посмотрите вот такой вариант реализации
Класс для создания условий
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
    public class RangeValue
    {
        /// <summary>Поле для хранения значения делегата функции</summary>
        private RangeExpression _expression;
 
        /// <summary>Делегат определяющий попадание в диапазон</summary>
        /// <param name="Range">Граница диапазона</param>
        /// <param name="Value">Значение</param>
        /// <returns>True если значение попадает в диапазон</returns>
        public delegate bool RangeExpression(double Range, double Value);
 
        /// <summary>Метод-свойство устанавливающий функцию сравнения</summary>
        public RangeExpression SetExpression { set => _expression = value; }
 
        /// <summary>Граница диапазона</summary>
        public double SourceValue { get; set; }
        /// <summary>Присваиваемое значение</summary>
        public double BOValue { get; set; }
 
        /// <summary>Метод вычисляющий попадание в диапазон</summary>
        /// <param name="Value">Значение для которого определяется попадание в диапазон</param>
        /// <returns>True если значение попало в диапазон</returns>
        public bool IsExpression(double Value)
            => _expression != null && _expression(SourceValue, Value);
 
        static public double CalcExpressions(double Value, List<RangeValue> Expressions, double DefaultValue = 0)
        {
            RangeValue expression = Expressions.OrderBy(expr => expr.SourceValue).FirstOrDefault(expr => expr.IsExpression(Value));
            return expression == null ? DefaultValue : expression.BOValue;
        }
    }
Пример его использование со списком условий из начала темы
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        static public void Main()
        {
            bool IsLessOrEqual(double Range, double Value) => Value <= Range;
            bool IsMore(double Range, double Value) => Value > Range;
 
            List<RangeValue> Expressions = new List<RangeValue>()
            {
                new RangeValue() {SourceValue=25, BOValue=2, SetExpression=IsMore},
                new RangeValue() {SourceValue=15, BOValue=0.5, SetExpression=IsLessOrEqual},
                new RangeValue() {SourceValue=20, BOValue=1, SetExpression=IsLessOrEqual},
                new RangeValue() {SourceValue=25, BOValue=1.5, SetExpression=IsLessOrEqual},
                new RangeValue() {SourceValue=10, BOValue=0, SetExpression=IsLessOrEqual}
            };
 
            for (int ind = 5; ind < 30; ind++)
                Console.WriteLine($" A={ind}, B={RangeValue.CalcExpressions(ind, Expressions, -100)}");
        }
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
23.11.2018, 21:48
Цитата Сообщение от wrq2017 Посмотреть сообщение
Поясните, пожалуйста, эту строку. Есть какой-то более длинный привычный эквивалент?
Это эквивалент
C#
1
2
3
4
5
double res;
if (rw != null)
    res = rw.BOValue;
else
    res = 0;
или
C#
1
double res = rw != null ? rw.BOValue : 0;
Там кстати в коде ошибка есть
C#
1
double max = MaxValue ?? double.NegativeInfinity; // тут должно быть быть PositiveInfinity...
0
3 / 3 / 2
Регистрация: 30.07.2017
Сообщений: 223
26.11.2018, 08:43  [ТС]
Цитата Сообщение от Someone007 Посмотреть сообщение
1
double max = MaxValue ?? double.NegativeInfinity; // тут должно быть быть PositiveInfinity...
Я заметил. Спасибо. А теперь у меня появилась новая идея. Что если вместо последовательного перебора правил

C#
1
RangeValue rw = rangeValues.FirstOrDefault(r => r.IsInRange(v));
преобразовать класс RangeValue таким образом, чтобы находить сначала среди коллекции условий то условие, граница которого наиболее близка к искомому числу, а уже затем определять - применять правило находящееся слева или справа от этой границы.
Так не быстрее будет?

Добавлено через 3 минуты
Цитата Сообщение от Элд Хасп Посмотреть сообщение
public delegate bool RangeExpression(double Range, double Value);
/// <summary>Метод-свойство устанавливающий функцию сравнения</summary>
* * * * public RangeExpression SetExpression { set => _expression = value; }
А как это вот сохранять в БД?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
26.11.2018, 13:55
Цитата Сообщение от wrq2017 Посмотреть сообщение
А как это вот сохранять в БД?
Делаете несколько стандартных статических делегатов: больше, меньше, равно и т.д. В базе сохраняете/восстанавливаете по их названиям.
Второй, способ можно сохранять в БД и функцию делегата, даже компилировать её во время исполнения, но в Вашем случае, такие сложности, по-моему, не нужны.
0
3 / 3 / 2
Регистрация: 30.07.2017
Сообщений: 223
27.11.2018, 09:02  [ТС]
Всем огромное спасибо за обсуждение вопроса! Тему можно считать закрытой.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
27.11.2018, 09:02

Написать алгоритм поиска данных методом линейного поиска
написать алгоритм поиска данных методом линейного поиска

Волновой алгоритм поиска (Алгоритм A* / Алгоритм А стар)
Хочу разработать алгоритм для решения головоломки с подвижными дисками (перестановочная головоломка). Определение. Перестано́вочные...

Алгоритм бинарного поиска (поиска делением пополам)
Необходимо реализовать алгоритм бинарного поиска (поиска делением пополам). Алгоритм в качестве входных данных получает массив...

Вывести элементы, присутствующие в обоих массивах А и В. Алгоритм сортировки - подсчетом, алгоритм поиска - двоичный
Вывести элементы, присутствующие в обоих массивах А и В. Алгоритм сортировки - подсчетом, алгоритм поиска - двоичный. Помогите пожалуйста...

Алгоритм поиска образа в строке. Алгоритм Бойера-Мура
# Лабораторная работа № 1 # Поиск образа в строке def forming_d(pattern): &quot;&quot;&quot; Формируем массив d.&quot;&quot;&quot; d...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
54
Ответ Создать тему
Новые блоги и статьи
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания источниках данных и элементов формы(текстовые поля и метки), опирается все это на технологию событий и мета. . .
Цена ошибки
DevAlt 23.08.2026
Человек я беспокойный и потому заинтересовался OCaml, в чате форсили функторы модулей как суперфичу. Пытаясь отдуплить концепт, наткнулся на тутор с простым примером. А главный принцип обучения от. . .
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
Жизня: рисунок укладки багажа, сделанный клодом
anaschu 21.08.2026
Сделал 15 снимков, он по снимкам сделал схему.
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
Мысли в слух
kumehtar 17.08.2026
Забавно, насколько сейчас стала доступна информация. Например о магии, духовном развитии, медитациях, и других подобных направлениях, ранее зачастую тайных, передаваемых от учителя к ученику. Хотя. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru