LINUX.ORG.RU

История изменений

Исправление Manhunt, (текущая версия) :

Писать начал вчера вечером, но не успел. Пока был занят, всё уже обсудили. Но, тем не менее, опубликую. Код не тестировался и даже не компилировался ни разу. Просто более-менее формальное изложение идеи. Разумеется, глобальные переменные нужно перенести в соответствующие классы, функции превратить в методы этих классов, константы сделать параметрами шаблонов. Но мне было лень.

массив фиксированного размер

#define ITEMS_MAX 100500
item_t items[ITEMS_MAX];

метод добавления элементов не определён(требуется указать в решении)

size_t slot_allocate();

size_t add_item(item_t item)
{
    size_t slot = slot_allocate();
    items[slot] = item;
    return slot;
}

метод извлечения элементов произвольный(то есть любой элемент можно извлечь вне зависимости от других элементов)

void slot_free(size_t slot);

item_t extract_item(size_t slot)
{
    item_t item = items[slot];
    slot_free(slot);
    return item;
}

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

#define LIST_HEAD_ALLOCATED (ITEMS_MAX)
#define LIST_HEAD_FREED     (ITEMS_MAX + 1)
#define LIST_SIZE           (ITEMS_MAX + 2)

size_t list_next[LIST_SIZE];
size_t list_prev[LIST_SIZE];

void list_init()
{
    for(size_t i = 0; i < LIST_SIZE; ++i)
    {
        list_next[i] = i;
        list_prev[i] = i;
    }
}

void list_remove(size_t i)
{
    size_t n = list_next[i];
    size_t p = list_prev[i];

    assert(list_next[p] == i);
    assert(list_prev[n] == i);

    list_next[p] = n;
    list_prev[n] = p;

    list_next[i] = i;
    list_prev[i] = i;
}

void list_insert(size_t prev, size_t i)
{
    list_remove(i);

    size_t p = prev;
    size_t n = list_next[prev];

    list_next[p] = i;
    list_prev[i] = p;

    list_next[i] = n;
    list_prev[n] = i;
}

void slot_free(size_t slot)
{
   list_insert(LIST_HEAD_FREED, slot);
}

size_t slot_allocate()
{
    size_t slot = list_prev[LIST_HEAD_FREED];
    if(slot == LIST_HEAD_FREED)
        slot = list_prev[LIST_HEAD_ALLOCATED];
    assert(slot < ITEMS_MAX);
    list_insert(LIST_HEAD_ALLOCATED, slot);
    return slot;
}

size_t slot_allocator_init()
{
    list_init();
    for(size_t i = 0; i < ITEMS_MAX; ++i)
        free_slot(i);
}

Исходная версия Manhunt, :

Писать начала вчера вечером, но не успел. Пока был занят, всё уже обсудили. Но, тем не менее, опубликую. Код не тестировался и даже не компилировался ни разу. Просто более-менее формальное изложение идеи. Разумеется, глобальные переменные нужно перенести в соответствующие классы, функции превратить в методы этих классов, константы сделать параметрами шаблонов. Но мне было лень.

массив фиксированного размер

#define ITEMS_MAX 100500
item_t items[ITEMS_MAX];

метод добавления элементов не определён(требуется указать в решении)

size_t slot_allocate();

size_t add_item(item_t item)
{
    size_t slot = slot_allocate();
    items[slot] = item;
    return slot;
}

метод извлечения элементов произвольный(то есть любой элемент можно извлечь вне зависимости от других элементов)

void slot_free(size_t slot);

item_t extract_item(size_t slot)
{
    item_t item = items[slot];
    slot_free(slot);
    return item;
}

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

#define LIST_HEAD_ALLOCATED (ITEMS_MAX)
#define LIST_HEAD_FREED     (ITEMS_MAX + 1)
#define LIST_SIZE           (ITEMS_MAX + 2)

size_t list_next[LIST_SIZE];
size_t list_prev[LIST_SIZE];

void list_init()
{
    for(size_t i = 0; i < LIST_SIZE; ++i)
    {
        list_next[i] = i;
        list_prev[i] = i;
    }
}

void list_remove(size_t i)
{
    size_t n = list_next[i];
    size_t p = list_prev[i];

    assert(list_next[p] == i);
    assert(list_prev[n] == i);

    list_next[p] = n;
    list_prev[n] = p;

    list_next[i] = i;
    list_prev[i] = i;
}

void list_insert(size_t prev, size_t i)
{
    list_remove(i);

    size_t p = prev;
    size_t n = list_next[prev];

    list_next[p] = i;
    list_prev[i] = p;

    list_next[i] = n;
    list_prev[n] = i;
}

void slot_free(size_t slot)
{
   list_insert(LIST_HEAD_FREED, slot);
}

size_t slot_allocate()
{
    size_t slot = list_prev[LIST_HEAD_FREED];
    if(slot == LIST_HEAD_FREED)
        slot = list_prev[LIST_HEAD_ALLOCATED];
    assert(slot < ITEMS_MAX);
    list_insert(LIST_HEAD_ALLOCATED, slot);
    return slot;
}

size_t slot_allocator_init()
{
    list_init();
    for(size_t i = 0; i < ITEMS_MAX; ++i)
        free_slot(i);
}