ИУП: интенсив 7 дней + диагностический пакет (32 вопроса, 9 задач с автопроверкой)
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
// Задача 03 — кольцевой буфер. Заполни реализации.
|
||||
#include <cstddef>
|
||||
|
||||
class RingBuffer {
|
||||
public:
|
||||
explicit RingBuffer(size_t capacity) : cap_(capacity), data_(new int[capacity ? capacity : 1]), size_(0) {}
|
||||
~RingBuffer() { delete[] data_; }
|
||||
|
||||
bool push(int v) {
|
||||
(void)v;
|
||||
return false; // TODO
|
||||
}
|
||||
|
||||
bool pop(int& out) {
|
||||
(void)out;
|
||||
return false; // TODO
|
||||
}
|
||||
|
||||
size_t size() const { return size_; }
|
||||
size_t capacity() const { return cap_; }
|
||||
bool empty() const { return size_ == 0; }
|
||||
bool full() const { return size_ == cap_; }
|
||||
|
||||
private:
|
||||
size_t cap_;
|
||||
int* data_;
|
||||
size_t size_;
|
||||
// добавь head_/tail_ по необходимости
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
# Задача 03 — кольцевой буфер (C++)
|
||||
|
||||
Кольцевой буфер фиксированной ёмкости — базовая структура для embedded и сетевого кода.
|
||||
|
||||
```c++
|
||||
class RingBuffer {
|
||||
public:
|
||||
explicit RingBuffer(size_t capacity);
|
||||
~RingBuffer();
|
||||
bool push(int v); // false, если буфер полон (перезапись НЕ делать)
|
||||
bool pop(int& out); // false, если буфер пуст
|
||||
size_t size() const;
|
||||
size_t capacity() const;
|
||||
bool empty() const;
|
||||
bool full() const;
|
||||
};
|
||||
```
|
||||
|
||||
Требования:
|
||||
- O(1) на push/pop, никаких сдвигов элементов;
|
||||
- память выделяется один раз в конструкторе, освобождается в деструкторе;
|
||||
- поведение после заворачивания индексов (wrap-around) корректное;
|
||||
- копирование запрещать не обязательно, но двойного освобождения быть не должно.
|
||||
|
||||
Проверка: `python3 grade.py 03`. Критерий: все `ok`, ASAN/UBSAN чистые.
|
||||
@@ -0,0 +1,46 @@
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include "solution.cpp"
|
||||
|
||||
static int failures = 0;
|
||||
#define CHECK(cond, name) do { if (cond) std::printf("ok %s\n", name); \
|
||||
else { std::printf("FAIL %s (line %d)\n", name, __LINE__); ++failures; } } while (0)
|
||||
|
||||
int main() {
|
||||
{
|
||||
RingBuffer rb(4);
|
||||
CHECK(rb.capacity() == 4 && rb.size() == 0 && rb.empty() && !rb.full(), "старт: пуст, ёмкость 4");
|
||||
CHECK(rb.push(1) && rb.push(2) && rb.push(3) && rb.push(4), "4 push прошли");
|
||||
CHECK(rb.full() && rb.size() == 4, "после 4 push буфер полон");
|
||||
CHECK(!rb.push(5), "push в полный буфер -> false");
|
||||
int v = -1;
|
||||
CHECK(rb.pop(v) && v == 1, "FIFO: первый pop == 1");
|
||||
CHECK(rb.pop(v) && v == 2, "FIFO: второй pop == 2");
|
||||
CHECK(rb.size() == 2 && !rb.full(), "после двух pop размер 2");
|
||||
CHECK(rb.push(5) && rb.push(6), "push после pop (заворачивание)");
|
||||
int expect[] = {3, 4, 5, 6};
|
||||
bool ok = true;
|
||||
for (int i = 0; i < 4; ++i) { int x = -1; ok = ok && rb.pop(x) && x == expect[i]; }
|
||||
CHECK(ok, "wrap-around: порядок 3,4,5,6");
|
||||
CHECK(rb.empty() && !rb.pop(v), "пустой буфер: pop -> false");
|
||||
}
|
||||
{
|
||||
RingBuffer rb(1);
|
||||
int v = 0;
|
||||
CHECK(rb.push(11) && !rb.push(12), "ёмкость 1: второй push отклонён");
|
||||
CHECK(rb.pop(v) && v == 11, "ёмкость 1: pop вернул 11");
|
||||
CHECK(rb.pop(v) == false, "ёмкость 1: второй pop -> false");
|
||||
}
|
||||
{
|
||||
RingBuffer rb(8);
|
||||
int cnt = 0;
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
if (rb.push(i)) cnt++;
|
||||
if (i % 3 == 0) { int x = -1; if (rb.pop(x)) cnt--; }
|
||||
}
|
||||
CHECK(cnt == (int)rb.size(), "длинный прогон: счётчик push/pop сходится с size()");
|
||||
CHECK(rb.size() <= 8, "длинный прогон: размер не превышает ёмкость");
|
||||
}
|
||||
std::printf(failures ? "\nFAILURES: %d\n" : "\nALL PASS\n", failures);
|
||||
return failures ? 1 : 0;
|
||||
}
|
||||
Reference in New Issue
Block a user