From 2d7e211154219c583e57d836e142cb0d19272f3b Mon Sep 17 00:00:00 2001 From: Timofeev_V_S Date: Sat, 28 Feb 2026 02:19:11 +0300 Subject: [PATCH 1/7] Timofeev_V_S_task_2 --- .../practice/randomSet/RandomSet.java | 151 +++++++++++++++++- 1 file changed, 146 insertions(+), 5 deletions(-) diff --git a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java index 8af477b5..8a71e906 100644 --- a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java +++ b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java @@ -1,21 +1,162 @@ package hse.java.lectures.lecture3.practice.randomSet; +import java.util.Random; + public class RandomSet { + private static final int INITIAL_CAPACITY = 16; + private static final double LOAD_FACTOR = 0.75; + private static final Object DELETED = new Object(); + + private Object[] elements; + private int size; + + // Хеш-таблица: два параллельных массива + private Object[] keys; + private int[] values; + private int tableSize; + private int entriesCount; + + private final Random random; + + public RandomSet() { + elements = new Object[INITIAL_CAPACITY]; + size = 0; + tableSize = INITIAL_CAPACITY; + keys = new Object[tableSize]; + values = new int[tableSize]; + for (int i = 0; i < tableSize; i++) { + values[i] = -1; + } + entriesCount = 0; + random = new Random(); + } + public boolean insert(T value) { - throw new UnsupportedOperationException("Not implemented"); + int index = findIndex(value); + if (index != -1 && keys[index] != DELETED && keys[index] != null && keys[index].equals(value)) { + return false; + } + + ensureCapacity(); + + int pos = findFreeSlot(value); + keys[pos] = value; + values[pos] = size; + entriesCount++; + + elements[size] = value; + size++; + + if (entriesCount > tableSize * LOAD_FACTOR) { + resizeTable(); + } + return true; } public boolean remove(T value) { - throw new UnsupportedOperationException("Not implemented"); + if (value == null) return false; + + int pos = findIndex(value); + if (pos == -1 || keys[pos] == DELETED || keys[pos] == null || !keys[pos].equals(value)) { + return false; // элемента нет + } + + int elementIndex = values[pos]; + + int lastIndex = size - 1; + T lastValue = (T) elements[lastIndex]; + + if (elementIndex != lastIndex) { + elements[elementIndex] = lastValue; + int lastPos = findIndex(lastValue); + if (lastPos != -1) { + values[lastPos] = elementIndex; + } + } + elements[lastIndex] = null; + + keys[pos] = DELETED; + values[pos] = -1; + entriesCount--; + + size--; + return true; } public boolean contains(T value) { - throw new UnsupportedOperationException("Not implemented"); + if (value == null) return false; + int pos = findIndex(value); + return pos != -1 && keys[pos] != DELETED && keys[pos] != null && keys[pos].equals(value); } public T getRandom() { - throw new UnsupportedOperationException("Not implemented"); + int randomIndex = random.nextInt(size); + return (T) elements[randomIndex]; + } + + private void ensureCapacity() { + if (size == elements.length) { + int newCapacity = elements.length * 2; + Object[] newElements = new Object[newCapacity]; + System.arraycopy(elements, 0, newElements, 0, size); + elements = newElements; + } + } + + private int findIndex(T key) { + int hash = key.hashCode(); + int start = Math.abs(hash % tableSize); + int i = start; + do { + if (keys[i] == null) { + return -1; + } + if (keys[i] != DELETED && keys[i].equals(key)) { + return i; + } + i = (i + 1) % tableSize; + } while (i != start); + return -1; } -} + private int findFreeSlot(T key) { + int hash = key.hashCode(); + int start = Math.abs(hash % tableSize); + int i = start; + do { + if (keys[i] == null || keys[i] == DELETED) { + return i; + } + i = (i + 1) % tableSize; + } while (i != start); + + throw new RuntimeException("("); + } + + private void resizeTable() { + int newTableSize = tableSize * 2; + Object[] newKeys = new Object[newTableSize]; + int[] newValues = new int[newTableSize]; + for (int i = 0; i < newTableSize; i++) { + newValues[i] = -1; + } + + for (int i = 0; i < size; i++) { + T elem = (T) elements[i]; + int hash = elem.hashCode(); + int start = Math.abs(hash % newTableSize); + int pos = start; + while (newKeys[pos] != null) { + pos = (pos + 1) % newTableSize; + } + newKeys[pos] = elem; + newValues[pos] = i; + } + + keys = newKeys; + values = newValues; + tableSize = newTableSize; + entriesCount = size; + } +} \ No newline at end of file From 824ad1537960f8512404f8bfd6dcba3dd67161c5 Mon Sep 17 00:00:00 2001 From: Timofeev_V_S Date: Sat, 28 Feb 2026 02:40:07 +0300 Subject: [PATCH 2/7] Timofeev_V_S_task_2 --- .../lectures/lecture3/practice/randomSet/RandomSet.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java index 8a71e906..d257e9e7 100644 --- a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java +++ b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java @@ -11,7 +11,6 @@ public class RandomSet { private Object[] elements; private int size; - // Хеш-таблица: два параллельных массива private Object[] keys; private int[] values; private int tableSize; @@ -59,7 +58,7 @@ public boolean remove(T value) { int pos = findIndex(value); if (pos == -1 || keys[pos] == DELETED || keys[pos] == null || !keys[pos].equals(value)) { - return false; // элемента нет + return false; } int elementIndex = values[pos]; @@ -78,12 +77,11 @@ public boolean remove(T value) { keys[pos] = DELETED; values[pos] = -1; - entriesCount--; + entriesCount--; size--; return true; } - public boolean contains(T value) { if (value == null) return false; int pos = findIndex(value); From 48963c0699d29cfb52f93f6c18915bebdce6f22c Mon Sep 17 00:00:00 2001 From: Timofeev_V_S Date: Sat, 28 Feb 2026 03:11:15 +0300 Subject: [PATCH 3/7] Timofeev_V_S_task_2 --- .../practice/randomSet/RandomSet.java | 202 ++++++++---------- 1 file changed, 88 insertions(+), 114 deletions(-) diff --git a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java index d257e9e7..70b68f7c 100644 --- a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java +++ b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java @@ -4,157 +4,131 @@ public class RandomSet { - private static final int INITIAL_CAPACITY = 16; - private static final double LOAD_FACTOR = 0.75; - private static final Object DELETED = new Object(); + private static class Node { + T key; + int index; + Node(T key, int index) { + this.key = key; + this.index = index; + } + } + + private final Node DELETED = new Node<>(null, -1); + private final Random random = new Random(); + private Node[] table; private Object[] elements; - private int size; + private int size = 0; + private int capacity = 4; + private final double loadFactor = 0.5; - private Object[] keys; - private int[] values; - private int tableSize; - private int entriesCount; + public RandomSet() { + table = new Node[capacity]; + elements = new Object[2]; + } - private final Random random; + private int hash(T key) { + return Math.abs(key.hashCode() % capacity); + } - public RandomSet() { - elements = new Object[INITIAL_CAPACITY]; - size = 0; - tableSize = INITIAL_CAPACITY; - keys = new Object[tableSize]; - values = new int[tableSize]; - for (int i = 0; i < tableSize; i++) { - values[i] = -1; + private void rehash() { + Node[] oldTable = table; + int oldCapacity = capacity; + + capacity *= 2; + table = new Node[capacity]; + + for (int i = 0; i < oldCapacity; i++) { + Node node = oldTable[i]; + if (node != null && node != DELETED) { + T key = node.key; + int idx = Math.abs(key.hashCode() % capacity); + while (table[idx] != null) { + idx = (idx + 1) % capacity; + } + table[idx] = new Node<>(key, node.index); + } } - entriesCount = 0; - random = new Random(); + } + + private int findPosition(T key) { + int index = hash(key); + for (int i = 0; i < capacity; i++) { + Node entry = table[index]; + if (entry == null) { + return -1; + } + if (entry != DELETED && entry.key.equals(key)) { + return index; + } + index = (index + 1) % capacity; + } + return -1; + } + + private void ensureElementsCapacity() { + if (size < elements.length) { + return; + } + int newCapacity = elements.length * 2; + Object[] newElements = new Object[newCapacity]; + System.arraycopy(elements, 0, newElements, 0, elements.length); + elements = newElements; } public boolean insert(T value) { - int index = findIndex(value); - if (index != -1 && keys[index] != DELETED && keys[index] != null && keys[index].equals(value)) { + if (findPosition(value) != -1) { return false; } - ensureCapacity(); + if (size >= capacity * loadFactor) { + rehash(); + } - int pos = findFreeSlot(value); - keys[pos] = value; - values[pos] = size; - entriesCount++; + int idx = hash(value); + while (table[idx] != null && table[idx] != DELETED) { + idx = (idx + 1) % capacity; + } + ensureElementsCapacity(); + int newElementIndex = size; elements[size] = value; size++; - if (entriesCount > tableSize * LOAD_FACTOR) { - resizeTable(); - } + table[idx] = new Node<>(value, newElementIndex); return true; } public boolean remove(T value) { - if (value == null) return false; - - int pos = findIndex(value); - if (pos == -1 || keys[pos] == DELETED || keys[pos] == null || !keys[pos].equals(value)) { + int pos = findPosition(value); + if (pos == -1) { return false; } - int elementIndex = values[pos]; - - int lastIndex = size - 1; - T lastValue = (T) elements[lastIndex]; + int removedIndex = table[pos].index; + table[pos] = DELETED; - if (elementIndex != lastIndex) { - elements[elementIndex] = lastValue; - int lastPos = findIndex(lastValue); + if (removedIndex != size - 1) { + T lastValue = (T) elements[size - 1]; + elements[removedIndex] = lastValue; + int lastPos = findPosition(lastValue); if (lastPos != -1) { - values[lastPos] = elementIndex; + table[lastPos].index = removedIndex; } } - elements[lastIndex] = null; - keys[pos] = DELETED; - values[pos] = -1; - - entriesCount--; size--; + elements[size] = null; + return true; } + public boolean contains(T value) { - if (value == null) return false; - int pos = findIndex(value); - return pos != -1 && keys[pos] != DELETED && keys[pos] != null && keys[pos].equals(value); + return findPosition(value) != -1; } public T getRandom() { int randomIndex = random.nextInt(size); return (T) elements[randomIndex]; } - - private void ensureCapacity() { - if (size == elements.length) { - int newCapacity = elements.length * 2; - Object[] newElements = new Object[newCapacity]; - System.arraycopy(elements, 0, newElements, 0, size); - elements = newElements; - } - } - - private int findIndex(T key) { - int hash = key.hashCode(); - int start = Math.abs(hash % tableSize); - int i = start; - do { - if (keys[i] == null) { - return -1; - } - if (keys[i] != DELETED && keys[i].equals(key)) { - return i; - } - i = (i + 1) % tableSize; - } while (i != start); - return -1; - } - - private int findFreeSlot(T key) { - int hash = key.hashCode(); - int start = Math.abs(hash % tableSize); - int i = start; - do { - if (keys[i] == null || keys[i] == DELETED) { - return i; - } - i = (i + 1) % tableSize; - } while (i != start); - - throw new RuntimeException("("); - } - - private void resizeTable() { - int newTableSize = tableSize * 2; - Object[] newKeys = new Object[newTableSize]; - int[] newValues = new int[newTableSize]; - for (int i = 0; i < newTableSize; i++) { - newValues[i] = -1; - } - - for (int i = 0; i < size; i++) { - T elem = (T) elements[i]; - int hash = elem.hashCode(); - int start = Math.abs(hash % newTableSize); - int pos = start; - while (newKeys[pos] != null) { - pos = (pos + 1) % newTableSize; - } - newKeys[pos] = elem; - newValues[pos] = i; - } - - keys = newKeys; - values = newValues; - tableSize = newTableSize; - entriesCount = size; - } } \ No newline at end of file From 4d52c2941950c6c1f5eebb06a54ddcf73fb15db6 Mon Sep 17 00:00:00 2001 From: Timofeev_V_S Date: Sat, 28 Feb 2026 03:20:12 +0300 Subject: [PATCH 4/7] Timofeev_V_S_task_2 --- .../lectures/lecture3/practice/randomSet/EmptySetException.java | 1 + .../hse/java/lectures/lecture3/practice/randomSet/RandomSet.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/EmptySetException.java b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/EmptySetException.java index c7820ac5..ffd150f8 100644 --- a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/EmptySetException.java +++ b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/EmptySetException.java @@ -3,5 +3,6 @@ public class EmptySetException extends RuntimeException { public EmptySetException(String message) { super(message); + } } diff --git a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java index 70b68f7c..9c83349e 100644 --- a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java +++ b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java @@ -12,6 +12,7 @@ private static class Node { this.key = key; this.index = index; } + } private final Node DELETED = new Node<>(null, -1); From bf82b019162a8fb66917c4cd8cf0f69a0c10764e Mon Sep 17 00:00:00 2001 From: Gomygomynomi <123175856+Gomygomynomi@users.noreply.github.com> Date: Sat, 28 Feb 2026 14:21:08 +0300 Subject: [PATCH 5/7] randomset: --- .../lectures/lecture3/practice/randomSet/EmptySetException.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/EmptySetException.java b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/EmptySetException.java index ffd150f8..50f4a964 100644 --- a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/EmptySetException.java +++ b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/EmptySetException.java @@ -4,5 +4,6 @@ public class EmptySetException extends RuntimeException { public EmptySetException(String message) { super(message); + } } From 847e33dc98da63bea06d0b5e09c1d8a3b1e2ba7b Mon Sep 17 00:00:00 2001 From: Timofeev_V_S Date: Sat, 28 Feb 2026 19:06:36 +0300 Subject: [PATCH 6/7] randomset: --- .../java/lectures/lecture3/practice/randomSet/RandomSet.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java index 9c83349e..50071c48 100644 --- a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java +++ b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java @@ -28,6 +28,7 @@ public RandomSet() { elements = new Object[2]; } + private int hash(T key) { return Math.abs(key.hashCode() % capacity); } @@ -129,6 +130,9 @@ public boolean contains(T value) { } public T getRandom() { + if (size == 0) { + throw new EmptySetException("RandomSet is empty"); + } int randomIndex = random.nextInt(size); return (T) elements[randomIndex]; } From 0697b3eaf26dd6cfb82aae403ceea368fc3077ba Mon Sep 17 00:00:00 2001 From: Timofeev_V_S Date: Sat, 28 Feb 2026 19:07:52 +0300 Subject: [PATCH 7/7] randomset: --- .../hse/java/lectures/lecture3/practice/randomSet/RandomSet.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java index 50071c48..408008d2 100644 --- a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java +++ b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/RandomSet.java @@ -129,6 +129,7 @@ public boolean contains(T value) { return findPosition(value) != -1; } + public T getRandom() { if (size == 0) { throw new EmptySetException("RandomSet is empty");