powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Бинарный поиск в С
14 сообщений из 39, страница 2 из 2
Бинарный поиск в С
    #39540933
Vladimir Baskakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7MBojenya7,

какое ещё условие нужно?
спасибо. сделал так
Код: plaintext
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.
int BinarySearch(int a[], int pos, int key, int *found)
{
    int first = 0;
    int last = pos;
    int mid;
    
    if (pos == 0)  //empty array
    {
        *found = 0;
        return 0;
    }
    else if (a[0] > key) 
    {
        *found = 0;
        return 0;
    }
    else if (a[pos - 1] < key)
    {
        *found = 0;
        return pos;
    }
    
    while (first < last)
    {
        mid = first + (last - first) / 2;

        if (key <= a[mid])
            last = mid;
        else
            first = mid + 1;
    }

    if (a[last] == key)
    {
        *found = 1;
        return last;
    }
    else
    {
        *found = 0;
        return last;
    }
}


похоже что работает.
....................................
а я бы возвращал положительное число, индекс+1 если найдено, а если не найдено - отрицательный индекс вставки - и параметр found тогда не нужен.

А чего изобретаете то? или так, язык поучить?
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39540940
Vladimir Baskakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
плохо сказал.
можно задачу ф-ции переформулировать так - найти индекс первого элемента, который больше или равен ключу.

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

параметр found точно не нужен.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541047
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
[quot Vladimir Baskakov]jenya7пропущено...


....................................
а я бы возвращал положительное число, индекс+1 если найдено, а если не найдено - отрицательный индекс вставки - и параметр found тогда не нужен.

А чего изобретаете то? или так, язык поучить?
Задача такая. Есть массив пакетов приходящих по TCP, в принципе не важно откуда они приходят.
Я должен хранить эти пакеты, для этого я создал массив пакетов. Глубина хранения пока 512 хотя может вырасти до пару тысяч, это еще TBD. То есть размер массива пока 512.
В приходящем пакете есть ИД и команда - добавить пакет, удалить пакет, редактировать пакет.
Доступ к пакету должен быть максимально быстрым. Находить ИД пакета простым перебором в for долго. Поэтому решил находить бинарным поиском и если ИД не найден вставлять его на его место, чтоб массив всегда был сортирован по ИД.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541058
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
пока что сделал так.
Код: plaintext
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.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
#define MESSAGE_SIZE 20
#define MESSAGE_ARR_SIZE  20

typedef struct TEST_MESSAGE_S
{
    int id;
    char data[MESSAGE_SIZE];
}TEST_MESSAGE;

TEST_MESSAGE messages[MESSAGE_ARR_SIZE];

char spectra_packet[20];

int  spectra_id;
int spectra_command;

int BinarySearch(TEST_MESSAGE a[], int pos, int key, int *found);
void InsertElement(int id, char *msg);
void DeleteElement(int id);

int BinarySearch(TEST_MESSAGE a[], int pos, int key, int *found)
{
    int first = 0;
    int last = pos;
    int mid;
    
    if (pos == 0)  //empty array
    {
        *found = 0;
        return 0;
    }
    else if (a[0].id > key) 
    {
        *found = 0;
        return 0;
    }
    else if (a[pos - 1].id < key)
    {
        *found = 0;
        return pos;
    }
    
    while (first < last)
    {
        mid = first + (last - first) / 2;

        if (key <= a[mid].id)
            last = mid;
        else
            first = mid + 1;
    }

    if (a[last].id == key)
    {
        *found = 1;
        return last;
    }
    else
    {
       *found = 0;
        return last;
    }
}

void UpdateElement(int id[, char msg[])
{
}

void InsertElement(int id, char *msg)
{
    int idx;
    
    idx = BinarySearch(messages, glob_pos, id, &found);
    
    if (found)  //command NEW but the element exists - issue UPDATE
    {
        UpdateElement(idx, msg);
    }
    else //element not found - add one
    {
        memmove(messages+(idx+1), messages+idx, sizeof(TEST_MESSAGE)*(glob_pos-idx));   //glob_pos-1-idx
        
        messages[idx].id = id;
        memcpy(messages[idx].data, msg, sizeof(spectra_packet));
        
       //if (glob_pos < MESSAGE_ARR_SIZE)
        glob_pos++;
    }
}

void DeleteElement(int id)
{
     int idx;
    
    idx = BinarySearch(messages, glob_pos, id, &found);
    
    if (found) 
    {
       memmove(messages+idx, messages+(idx+1), sizeof(TEST_MESSAGE)*glob_pos-1-idx);
       
       if (glob_pos > 0)
           glob_pos--;
    }
}
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541062
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
тестирую так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
 /////////////////////////////TEST  AREA ///////////////////////////////////
  for (idx = 0; idx < 20; idx++)
  {
      messages[idx].id = -1;
  }
  
  while(1)
  {
      spectra_id = spectra_packet[0];
      spectra_command = spectra_packet[1];
      
      switch (spectra_command)
      {
            case 1:
                if (glob_pos < MESSAGE_ARR_SIZE)
                    InsertElement(spectra_id, spectra_packet);
            break;
            case 2:
                DeleteElement(spectra_id);
            break;
      }
  }
/////////////////////////////////////////////////////////////////////



пока вроде вставка и удаление проходят нормально.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541106
Vladimir Baskakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задача такая. Есть массив пакетов приходящих по TCP, в принципе не важно откуда они приходят.
Я должен хранить эти пакеты, для этого я создал массив пакетов. Глубина хранения пока 512 хотя может вырасти до пару тысяч, это еще TBD. То есть размер массива пока 512.
В приходящем пакете есть ИД и команда - добавить пакет, удалить пакет, редактировать пакет.
Доступ к пакету должен быть максимально быстрым. Находить ИД пакета простым перебором в for долго. Поэтому решил находить бинарным поиском и если ИД не найден вставлять его на его место, чтоб массив всегда был сортирован по ИД.

чисто теоретически,
https://habrahabr.ru/post/65617/
https://ru.wikipedia.org/wiki/B-дерево
есть разные упорядоченные структуры данных для хранения сортированных данных
- всякие бинарные и сбалансированные деревья. может быть среди них поискать.

или - хэш-таблицы. чтобы по целому вычислять ключик, где искать - в каком сегменте, и там уже перебором или бинарным поиском. Мне думается, что хэширование - поможет.

допустим, если храним 2000 значений - захешировали на сотню, и вот уже в каждом массивчике перебираемых 20 единиц (в среднем) - и вставлять быстро и искать нормально. А перерасход памяти для такого количества значений - мизернейший.


============================
всего доброго.

PS
а почему си, а не с++ с огромным массивом оптимизированных уже библиотек? ну дело хозяйское, в целом.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541245
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vladimir BaskakovЗадача такая. Есть массив пакетов приходящих по TCP, в принципе не важно откуда они приходят.
Я должен хранить эти пакеты, для этого я создал массив пакетов. Глубина хранения пока 512 хотя может вырасти до пару тысяч, это еще TBD. То есть размер массива пока 512.
В приходящем пакете есть ИД и команда - добавить пакет, удалить пакет, редактировать пакет.
Доступ к пакету должен быть максимально быстрым. Находить ИД пакета простым перебором в for долго. Поэтому решил находить бинарным поиском и если ИД не найден вставлять его на его место, чтоб массив всегда был сортирован по ИД.

чисто теоретически,
https://habrahabr.ru/post/65617/
https://ru.wikipedia.org/wiki/B-дерево
есть разные упорядоченные структуры данных для хранения сортированных данных
- всякие бинарные и сбалансированные деревья. может быть среди них поискать.

или - хэш-таблицы. чтобы по целому вычислять ключик, где искать - в каком сегменте, и там уже перебором или бинарным поиском. Мне думается, что хэширование - поможет.

допустим, если храним 2000 значений - захешировали на сотню, и вот уже в каждом массивчике перебираемых 20 единиц (в среднем) - и вставлять быстро и искать нормально. А перерасход памяти для такого количества значений - мизернейший.


============================
всего доброго.

PS
а почему си, а не с++ с огромным массивом оптимизированных уже библиотек? ну дело хозяйское, в целом.
я думал про хэш. но пока остановились на бинарном поиске.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541255
Vladimir Baskakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а почему? может быть на макете сверить производительность?

от целого хэш-функция на 10 000 значений посчитается практически влет, и скорее всего в каждом из этих 10000 массивов будет сидеть ну три, ну пять ключей. если всего значений 2000.

Хэширование даст заметно - лучшее масштабирование при увеличении кол-ва эл-тов, сокращая расходы на вставку - меньше памяти надо двигать. ну конечно по ситуации - если код для микроконтроллера - это одно, а если для машинки с кучей памяти под современной осью - совсем другое.

но, не настаиваю. кому как удобнее.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541259
jenya7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vladimir Baskakovа почему? может быть на макете сверить производительность?

от целого хэш-функция на 10 000 значений посчитается практически влет, и скорее всего в каждом из этих 10000 массивов будет сидеть ну три, ну пять ключей. если всего значений 2000.

Хэширование даст заметно - лучшее масштабирование при увеличении кол-ва эл-тов, сокращая расходы на вставку - меньше памяти надо двигать. ну конечно по ситуации - если код для микроконтроллера - это одно, а если для машинки с кучей памяти под современной осью - совсем другое.

но, не настаиваю. кому как удобнее.
я представил две опции. но народ выбрал бинарный поиск. я не стал спорить. если будем терять пакеты попробуем хэш. есть еще красно-черное дерево которое, как говорят, на больших массивах дает хорошие результаты.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541268
Vladimir Baskakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
что еще по ходу подумалось (я уже давным-давно не сишник, по старой памяти)

char * strchr( const char * string, int symbol);

вроде бы эффективно задействует возможности процессора для поиска в области памяти.
вроде бы scas http://programm.ws/page.php?id=129

может быть не сортировать, а искать на уровне байт? найти первый байт искомого числа. проверить совпадение следующих.

мне кажется тут есть о чем подумать, если уж надо очень, очень быстро искать в сравнительно-небольших массивах, до 10-20 килобайт

вплоть до того, что весь массив в котором ищем держать в строковом виде 16-ричных чисел и искать там строковыми, высокооптимизированными ф-циями, которые были и есть в составе стандартной б-ки Си.

то есть, вариантов на попробовать, даже в самом простом случае, море.

Попробуйте, шутки ради, вдруг да выйдет....
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541270
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7я думал про хэш. но пока остановились на бинарном поиске.
Тут выбор между быстро искать и и быстро вставлять/удалять. Бинарный поиск ищет достаточно быстро, не факт что хэштаблица будет искать быстрее при нескольких тысячах элементов. Но вставка/удаление требует сдвига существенной части массива, что не быстро.
Если вставок/удалений относительно немного, то твой способ будет нормально работать. Надо просто затестить с нагрузкой похожей на реальную. Если производительность устроит, то можешь оставить как есть.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541274
Vladimir Baskakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jenya7я представил две опции. но народ выбрал бинарный поиск. я не стал спорить. если будем терять пакеты попробуем хэш. есть еще красно-черное дерево которое, как говорят, на больших массивах дает хорошие результаты.

а время то меряли? профилировали? может и не пробежка по несортированному массиву его занимает? а какая-то предобработка, принятие пакетов, или постобработка?

ну, я против народа то не пойду.... народ сказал, значит так надо.
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541276
Vladimir Baskakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tjenya7я думал про хэш. но пока остановились на бинарном поиске.
Тут выбор между быстро искать и и быстро вставлять/удалять. Бинарный поиск ищет достаточно быстро, не факт что хэштаблица будет искать быстрее при нескольких тысячах элементов. Но вставка/удаление требует сдвига существенной части массива, что не быстро.
Если вставок/удалений относительно немного, то твой способ будет нормально работать. Надо просто затестить с нагрузкой похожей на реальную. Если производительность устроит, то можешь оставить как есть.

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

(шутка) надеюсь, это курсовичок, а не атомный ледокол с горячей заменой кода на проде. когда бесконечный цикл не даст опустить графитовый стерженек....( конец шутки)
...
Рейтинг: 0 / 0
Бинарный поиск в С
    #39541347
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir Baskakov,

шутка про дельфи за 300 ?
...
Рейтинг: 0 / 0
14 сообщений из 39, страница 2 из 2
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Бинарный поиск в С
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]