7-6 Пул объектов (object_pool) Оценка 10 Ответы на вступительные вопросы PTA C++

7-6 Пул объектов (object_pool)

оценка 10

Просмотр тем в полноэкранном режиме

переключить раскладку

Автор Ван Чжэн Юнит Шаньдунский университет

В Java есть функция сборки мусора (GC), которая может освобождать такие ресурсы, как память и объекты, которые больше нельзя использовать. Но C++ сам отвечает за освобождение динамически выделяемых ресурсов. Как разработчик программного обеспечения я чувствую, что бремя на моих плечах еще тяжелее. Так как же реализовано управление ресурсами? Я нашел решение начального уровня для реализации пула объектов с использованием технологии свободных списков .

Например, если имеется пул объектов C с емкостью Object pool[C + 1] (№ 0 — это фиктивный элемент, который не используется), используйте свободный список для управления им. Говорят, что связный список C++ должен использовать всеми любимые и уважаемые указатели , но указатели только что были упомянуты, и уже слишком поздно, поэтому я сначала использую индекс массива для имитации указателей.

  • Создайте главный индекс и массив-наследник списка свободных : int head = 1, next[C + 1];

  • head равен 0 означает, что свободного юнита нет, в противном случае это означает индекс следующего свободного юнита

  • Инициализация: next[1] = 2, next[2] = 3, ... next[C] = 0;

Моделируйте, используя:

  • Объект размещения: новый

  • Если head == 0, доступных юнитов нет, просто верните 0.

  • Если head != 0, используйте p, чтобы сохранить текущее значение head, измените head на next[head] и верните p, чтобы указать, что объект pool[p] можно использовать.

  • Справочный объект: ref p

  • Если p действителен (в диапазоне [1, C] и был выделен), выведите ok

  • иначе ошибка

  • Освободить объект: удалить p

  • Если p == 0, просто выведите голову. C/C++ оговаривается таким образом, позволяя освобождать (NULL) или удалять nullptr).

  • Если p != 0, запрашивается возврат блока pool[p]:

  • Если p действителен (в диапазоне [1, C] и был выделен), поместите его в начало списка свободных мест: next[p] = head; head = p;.

  • Если неверно, вывести ошибку

Цель: попрактиковаться в методах работы с массивами, циклами, моделированием событий и свободными связными списками; помочь в понимании указателей.

входные характеристики

  • В первой строке задается емкость C пула объектов, где C — целое положительное число, меньшее 65536.

  • Последующие запросы на выделение и освобождение нескольких строк обрабатываются до EOF. Количество запросов меньше 65536.

  • новая операция распределения

  • ref x относится к единице x

  • удалить x освобождает блок x

выходная спецификация

  • Первая строка вывода: capacity <C> # head=1

  • Затем обработайте операции одну за другой:

  • Вывести операцию и параметры, пробел, #, пробел, результат операции как есть

  • Результаты операции следующие:

  • Распределение: new # return <p>, head=<h> Выведите индекс выделенного модуля p и индекс свободного заголовка h после выделения.

  • Возвращает 0, если нет свободных ячеек.

  • Цитата: ref<p> # ок или ref <p> # ошибка

  • освобожден:

  • delete <p> # head=<h>, где p — индекс освобожденной единицы, а h — скорректированный индекс свободной головки.

  • Если p недействителен, выведите ошибку

образец ввода

capacity 2
new   
ref 1
new   
new   
delete 2 
ref 2
delete 2 
delete 9 
delete 0 
new   
delete 1 
new   
delete 1 
delete 2 

образец вывода

capacity 2 # head=1
new # return 1, head=2
ref 1 # ok
new # return 2, head=0
new # return 0, head=0
delete 2 # head=2
ref 2 # error
delete 2 # error
delete 9 # error
delete 0 # head=2
new # return 2, head=0
delete 1 # head=1
new # return 1, head=0
delete 1 # head=1
delete 2 # head=2

Ограничение длины кода 16 КБ

Ограничение по времени 400 мс

Ограничение памяти 64 МБ

Отвечать

#include<iostream>
#include<vector>
#include <bitset> 
using namespace std;
template<typename T>
class ObjectPool
{
private:
    vector<T*> pool;
    bitset<65537> is_vaid;
    int head = 1,C;
    vector<int> next;
public:
    ObjectPool(int c)
    {
        C = c;
        for (int i = 0; i < c; ++i)
        {
            next.push_back(i+1);
            pool.push_back(new T());
            is_vaid[i] = 0;
        }
        pool.push_back(new T());
        next.push_back(0);
    }
    int createNew()
    {
        if (head == 0)return 0;
        else if (head != 0)
        {
            int p;
            p = head;
            head = next[head];
            is_vaid[p] = 1;
            //printf("\n2\n");
            return p;
        }
        return 0;
    }
    T* ref(int p)
    {
        //cout << endl << "h" << endl;
        if (p<1 || p>C)return nullptr;
        //cout << endl << "h" << endl;
        if (is_vaid[p]==1)
        {
            //cout << endl << pool[p] << endl;
            return pool[p];
        }
        return nullptr;
    }
    int deleteObject(int p)
    {
        if (p == 0)return head;
        else
        {
            if (p >= 1 && p <= C && is_vaid[p]==1)
            {
                next[p] = head;
                head = p;
                return head;
            }
        }
        return 0;
    }
    int getHead()
    {
        //printf("\n1\n");
        return head;
    }
};

int main()
{
    int C,i;
    scanf("capacity %d", &C);
    
    ObjectPool<int>* object_pool = new ObjectPool<int>(C);
    int* int_ptr=nullptr;
    char c;
    c = getchar();
    while (c != EOF)
    {
        c = getchar();
        switch (c)
        {
        case 'n':
            scanf("ew");
            i = object_pool->createNew();
            printf("new # return %d, head=%d\n", i, object_pool->getHead());
            break;
        case 'r':
            scanf("ef %d", &i);
            int_ptr =object_pool->ref(i);

            if (int_ptr == nullptr)
            {
                printf("ref %d # error\n", i);
            }
            else
            {
                printf("ref %d # ok\n", i);
            }
            break;
        case 'd':
            scanf("elete %d", &i);
            if (object_pool->deleteObject(i) !=0)
            {
                printf("delete %d # head=%d\n", i, object_pool->getHead());
            }
            else
            {
                printf("delete %d # error\n", i);
            }
            break;
        case EOF:
            return 0;
        }
    }
}

おすすめ

転載: blog.csdn.net/lifesize/article/details/128944964
おすすめ