← Назад к вопросам
Реализация Set на основе List
2.0 Middle🔥 121 комментариев
#Коллекции и структуры данных#Тестирование
Условие
Реализовать структуру данных Set с использованием List в качестве внутреннего хранилища.
Интерфейс:
class MySet<T> {
fun count(): Int // количество элементов
fun add(element: T): Boolean // true если добавлен
fun remove(element: T): Boolean // true если удалён
fun contains(element: T): Boolean
fun clear()
}
Требования:
- Не использовать стандартные Set реализации
- Элементы не должны дублироваться
- add() возвращает false если элемент уже есть
- remove() возвращает false если элемента нет
Тесты:
val set = MySet<Int>()
assert(set.add(1) == true)
assert(set.add(1) == false)
assert(set.count() == 1)
assert(set.contains(1) == true)
assert(set.remove(1) == true)
assert(set.remove(1) == false)
Бонус:
- Реализовать итератор
- Добавить операции union, intersection, difference
- Оценить сложность операций
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Решение: Реализация Set на основе List
1. Базовая реализация MySet
class MySet<T> {
private val elements: MutableList<T> = mutableListOf()
fun count(): Int = elements.size
fun add(element: T): Boolean {
if (contains(element)) {
return false
}
elements.add(element)
return true
}
fun remove(element: T): Boolean {
return elements.remove(element)
}
fun contains(element: T): Boolean {
return elements.contains(element)
}
fun clear() {
elements.clear()
}
fun isEmpty(): Boolean = elements.isEmpty()
fun toList(): List<T> = elements.toList()
}
2. Реализация с итератором
class MySet<T> : Iterable<T> {
private val elements: MutableList<T> = mutableListOf()
fun count(): Int = elements.size
fun add(element: T): Boolean {
if (contains(element)) return false
elements.add(element)
return true
}
fun remove(element: T): Boolean {
return elements.remove(element)
}
fun contains(element: T): Boolean {
return elements.contains(element)
}
fun clear() {
elements.clear()
}
override fun iterator(): Iterator<T> = elements.iterator()
fun toList(): List<T> = elements.toList()
}
3. Операции над множествами
class MySet<T> : Iterable<T> {
private val elements: MutableList<T> = mutableListOf()
fun count(): Int = elements.size
fun add(element: T): Boolean {
if (contains(element)) return false
elements.add(element)
return true
}
fun remove(element: T): Boolean {
return elements.remove(element)
}
fun contains(element: T): Boolean {
return elements.contains(element)
}
fun clear() {
elements.clear()
}
fun union(other: MySet<T>): MySet<T> {
val result = MySet<T>()
elements.forEach { result.add(it) }
other.elements.forEach { result.add(it) }
return result
}
fun intersection(other: MySet<T>): MySet<T> {
val result = MySet<T>()
elements.forEach { element ->
if (other.contains(element)) {
result.add(element)
}
}
return result
}
fun difference(other: MySet<T>): MySet<T> {
val result = MySet<T>()
elements.forEach { element ->
if (!other.contains(element)) {
result.add(element)
}
}
return result
}
fun isSubsetOf(other: MySet<T>): Boolean {
return elements.all { other.contains(it) }
}
fun isSupersetOf(other: MySet<T>): Boolean {
return other.isSubsetOf(this)
}
override fun iterator(): Iterator<T> = elements.iterator()
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is MySet<*>) return false
if (count() != other.count()) return false
return elements.all { other.contains(it) }
}
override fun hashCode(): Int {
return elements.fold(0) { acc, element ->
acc + (element?.hashCode() ?: 0)
}
}
override fun toString(): String = elements.toString()
}
4. Unit Тесты
class MySetTest {
@Test
fun testAddElement() {
val set = MySet<Int>()
assertTrue(set.add(1))
assertEquals(1, set.count())
}
@Test
fun testAddDuplicate() {
val set = MySet<Int>()
assertTrue(set.add(1))
assertFalse(set.add(1))
assertEquals(1, set.count())
}
@Test
fun testContains() {
val set = MySet<Int>()
set.add(1)
assertTrue(set.contains(1))
assertFalse(set.contains(2))
}
@Test
fun testRemove() {
val set = MySet<Int>()
set.add(1)
assertTrue(set.remove(1))
assertFalse(set.remove(1))
assertEquals(0, set.count())
}
@Test
fun testClear() {
val set = MySet<Int>()
set.add(1)
set.add(2)
set.clear()
assertEquals(0, set.count())
}
@Test
fun testUnion() {
val set1 = MySet<Int>()
val set2 = MySet<Int>()
set1.add(1)
set1.add(2)
set2.add(2)
set2.add(3)
val union = set1.union(set2)
assertEquals(3, union.count())
assertTrue(union.contains(1))
assertTrue(union.contains(2))
assertTrue(union.contains(3))
}
@Test
fun testIntersection() {
val set1 = MySet<Int>()
val set2 = MySet<Int>()
set1.add(1)
set1.add(2)
set1.add(3)
set2.add(2)
set2.add(3)
set2.add(4)
val intersection = set1.intersection(set2)
assertEquals(2, intersection.count())
assertTrue(intersection.contains(2))
assertTrue(intersection.contains(3))
assertFalse(intersection.contains(1))
}
@Test
fun testDifference() {
val set1 = MySet<Int>()
val set2 = MySet<Int>()
set1.add(1)
set1.add(2)
set1.add(3)
set2.add(2)
set2.add(4)
val difference = set1.difference(set2)
assertEquals(2, difference.count())
assertTrue(difference.contains(1))
assertTrue(difference.contains(3))
assertFalse(difference.contains(2))
}
@Test
fun testIterator() {
val set = MySet<Int>()
set.add(1)
set.add(2)
set.add(3)
val elements = set.toList()
assertEquals(3, elements.size)
assertTrue(elements.contains(1))
}
@Test
fun testEquality() {
val set1 = MySet<Int>()
val set2 = MySet<Int>()
set1.add(1)
set1.add(2)
set2.add(2)
set2.add(1)
assertEquals(set1, set2)
}
}
5. Анализ сложности операций
| Операция | Сложность | Примечание |
|---|---|---|
| add | O(n) | Проверка contains + добавление |
| remove | O(n) | Линейный поиск элемента |
| contains | O(n) | Линейный поиск в списке |
| count | O(1) | Возврат размера |
| clear | O(1) | Очистка списка |
| union | O(n*m) | Для каждого элемента проверка |
| intersection | O(n*m) | Двойной перебор элементов |
| difference | O(n*m) | Двойной перебор элементов |
Оптимизация производительности
Для оптимизации можно использовать HashMap:
class OptimizedSet<T> {
private val map = mutableMapOf<T, Boolean>()
fun add(element: T): Boolean {
if (contains(element)) return false
map[element] = true
return true
}
fun contains(element: T): Boolean {
return map.containsKey(element)
}
}
Это уменьшит сложность операций до O(1) в среднем случае.
Ключевые особенности
- Уникальность элементов: Автоматически обеспечивается проверкой contains
- Итератор: Позволяет перебирать элементы
- Операции над множествами: union, intersection, difference
- Равенство: Два набора равны если содержат одни элементы
- Простота: Чистая реализация на List
Это полнофункциональная реализация Set с полной поддержкой операций над множествами.