Files

236 lines
7.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: 587d8255367417b2b2512c75
title: Створення кругової черги
challengeType: 1
forumTopicId: 301625
dashedName: create-a-circular-queue
---
# --description--
У цьому завданні ви навчитеся створювати кругову чергу. Циклічна черга - це черга фіксованого розміру, яка записує до кінця набору даних, а потім починає перезаписувати її початок. Цей тип структури даних є корисним у певних ситуаціях. Наприклад, кругову чергу можна використати для медіапотоку. Після заповнення черги нові медіадані перезапишуть старі.
Добре проілюструвати цю концепцію можна за допомогою масиву довжиною `5`:
```js
[null, null, null, null, null]
^Read @ 0
^Write @ 0
```
Тут і читання, і запис знаходяться на позиції `0`. Зараз черга отримує 3 нові записи `a`, `b` і `c`. Тепер наша черга виглядає так:
```js
[a, b, c, null, null]
^Read @ 0
^Write @ 3
```
При зчитуванні вказівник читання може видаляти або залишати значення:
```js
[null, null, null, null, null]
^Read @ 3
^Write @ 3
```
Тепер ми записуємо у чергу значення `d`, `e` і `f`. Як тільки запис досягне кінця масиву, він повернеться до початку:
```js
[f, null, null, d, e]
^Read @ 3
^Write @ 1
```
Цей підхід потребує сталого обсягу пам'яті, але дозволяє обробляти файли набагато більшого розміру.
# --instructions--
У цьому завданні ми реалізуємо кругову чергу. Кругова черга повинна забезпечувати методи `enqueue` і `dequeue`, які дозволять читати з черги та записувати в неї. Сам клас також повинен прийняти цілий аргумент, який визначає розмір черги при її створенні. Ми написали початкову версію цього класу для вас у редакторі коду.
Коли ви записуєте елементи в чергу, то вказівник запису повинен рухатись вперед і повернутися до початку після того, як він досягне кінця черги. В разі успішного додавання метод `enqueue` повинен повернути доданий елемент; в іншому випадку він поверне `null`.
Аналогічно при видаленні елементів з черги вказівник читання повинен рухатись вперед. Під час видалення елементу з черги, повинен повертатися цей елемент. Якщо ви не можете отримати елемент - повинен повернутися `null`.
Вказівник запису не може пройти повз вказівника зчитування (наш клас не дозволить переписати дані, які ще не були зчитаними), і вказівник зчитування не може пройти повз дані, що ви записали.
# --hints--
Метод `enqueue` повинен додати елементи до кругової черги.
```js
assert(
(function () {
var test = new CircularQueue(3);
test.enqueue(17);
test.enqueue(32);
test.enqueue(591);
var print = test.print();
return print[0] === 17 && print[1] === 32 && print[2] === 591;
})()
);
```
Ви не можете записати елементи повз вказівника зчитування.
```js
assert(
(function () {
var test = new CircularQueue(3);
test.enqueue(17);
test.enqueue(32);
test.enqueue(591);
test.enqueue(13);
test.enqueue(25);
test.enqueue(59);
var print = test.print();
return print[0] === 17 && print[1] === 32 && print[2] === 591;
})()
);
```
Метод `dequeue` повинен отримати елементи з черги.
```js
assert(
(function () {
var test = new CircularQueue(3);
test.enqueue(17);
test.enqueue(32);
test.enqueue(591);
return (
test.dequeue() === 17 && test.dequeue() === 32 && test.dequeue() === 591
);
})()
);
```
Після того як елемент був отриманий, його позиція в черзі повинна бути скинути до `null`.
```js
assert(
(function () {
var test = new CircularQueue(3);
test.enqueue(17);
test.enqueue(32);
test.enqueue(672);
test.dequeue();
test.dequeue();
var print = test.print();
return print[0] === null && print[1] === null && print[2] === 672;
})()
);
```
Спроба отримання елемента повз вказівника запиту повинна повернути `null` і не обганяє значення вказівника запису.
```js
assert(
(function () {
var test = new CircularQueue(3);
test.enqueue(17);
test.enqueue(32);
test.enqueue(591);
return (
test.dequeue() === 17 &&
test.dequeue() === 32 &&
test.dequeue() === 591 &&
test.dequeue() === null &&
test.dequeue() === null &&
test.dequeue() === null &&
test.dequeue() === null &&
test.enqueue(100) === 100 &&
test.dequeue() === 100
);
})()
);
```
# --seed--
## --seed-contents--
```js
class CircularQueue {
constructor(size) {
this.queue = [];
this.read = 0;
this.write = 0;
this.max = size - 1;
while (size > 0) {
this.queue.push(null);
size--;
}
}
print() {
return this.queue;
}
enqueue(item) {
// Only change code below this line
// Only change code above this line
}
dequeue() {
// Only change code below this line
// Only change code above this line
}
}
```
# --solutions--
```js
class CircularQueue {
constructor(size) {
this.queue = [];
this.read = 0;
this.write = 0;
this.max = size - 1;
while (size > 0) {
this.queue.push(null);
size--;
}
}
print() {
return this.queue;
}
enqueue(item) {
// Only change code below this line
console.log(this.write, this.max);
if (this.queue[this.write] === null) {
this.queue[this.write++] = item;
if (this.write > this.max) {
this.write = 0;
}
return item;
}
return null;
// Only change code above this line
}
dequeue() {
// Only change code below this line
if (this.queue[this.read] !== null) {
let item = this.queue[this.read];
this.queue[this.read++] = null;
if (this.read > this.max) {
this.read = 0;
}
return item;
}
return null;
// Only change code above this line
}
}
```