using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Prac8 { public class MyList : IEnumerable { private const int DefaultCapacity = 4; private T[] _items; private int _count; public MyList(int capacity = DefaultCapacity) { if (capacity < 1) { capacity = DefaultCapacity; } _items = new T[capacity]; _count = 0; } public int Count => _count; public T this[int index] { get => Get(index); set { ValidateIndex(index); _items[index] = value; } } public void Add(T item) { EnsureCapacity(); _items[_count] = item; _count++; } public void Insert(int index, T item) { ValidateInsertIndex(index); EnsureCapacity(); for (int i = _count; i > index; i--) { _items[i] = _items[i - 1]; } _items[index] = item; _count++; } public void AddRange(MyList otherList) { if (otherList == null) { throw new ArgumentNullException(nameof(otherList), "Другой список не должен быть null."); } MyList source = CreateSafeCopy(otherList); EnsureCapacityFor(source.Count); foreach (T item in source) { Add(item); } } public void InsertRange(int index, MyList otherList) { ValidateInsertIndex(index); if (otherList == null) { throw new ArgumentNullException(nameof(otherList), "Другой список не должен быть null."); } if (otherList.Count == 0) { return; } MyList source = CreateSafeCopy(otherList); EnsureCapacityFor(source.Count); for (int i = _count - 1; i >= index; i--) { _items[i + source.Count] = _items[i]; } int insertPosition = index; foreach (T item in source) { _items[insertPosition] = item; insertPosition++; } _count += source.Count; } public void RemoveAt(int index) { ValidateIndex(index); for (int i = index; i < _count - 1; i++) { _items[i] = _items[i + 1]; } _count--; _items[_count] = default(T); } public void RemoveLast() { if (_count == 0) { throw new InvalidOperationException("Нельзя удалить последний элемент из пустого списка."); } _count--; _items[_count] = default(T); } public void RemoveRange(int firstIndex, int secondIndex) { if (_count == 0) { throw new InvalidOperationException("Список пуст."); } ValidateIndex(firstIndex); ValidateIndex(secondIndex); if (firstIndex > secondIndex) { throw new ArgumentException("Первый индекс не может быть больше второго."); } int removeCount = secondIndex - firstIndex + 1; for (int i = firstIndex; i < _count - removeCount; i++) { _items[i] = _items[i + removeCount]; } for (int i = _count - removeCount; i < _count; i++) { _items[i] = default(T); } _count -= removeCount; } public void Clear() { for (int i = 0; i < _count; i++) { _items[i] = default(T); } _count = 0; } public T Get(int index) { ValidateIndex(index); return _items[index]; } public void Print() { if (_count == 0) { Console.WriteLine("Список пуст."); return; } for (int i = 0; i < _count; i++) { Console.WriteLine($"[{i}] {_items[i]}"); } } public T Find(Predicate match) { if (match == null) { throw new ArgumentNullException(nameof(match), "Предикат не должен быть null."); } for (int i = 0; i < _count; i++) { if (match(_items[i])) { return _items[i]; } } return default(T); } public void EnsureCapacity() { if (_count < _items.Length) { return; } int newCapacity = _items.Length == 0 ? DefaultCapacity : _items.Length * 2; Array.Resize(ref _items, newCapacity); } public void Sort(int index) { if (index != 0 && index != 1) { throw new ArgumentException("Для сортировки используйте 1 - по возрастанию или 0 - по убыванию."); } if (_count < 2) { return; } Comparer comparer = Comparer.Default; bool ascending = index == 1; for (int i = 0; i < _count - 1; i++) { int selectedIndex = i; for (int j = i + 1; j < _count; j++) { int compareResult = comparer.Compare(_items[j], _items[selectedIndex]); if ((ascending && compareResult < 0) || (!ascending && compareResult > 0)) { selectedIndex = j; } } if (selectedIndex != i) { T temp = _items[i]; _items[i] = _items[selectedIndex]; _items[selectedIndex] = temp; } } } public void Reverse() { int left = 0; int right = _count - 1; while (left < right) { T temp = _items[left]; _items[left] = _items[right]; _items[right] = temp; left++; right--; } } public void Distinct() { if (_count < 2) { return; } EqualityComparer comparer = EqualityComparer.Default; T[] uniqueItems = new T[Math.Max(DefaultCapacity, _count)]; int uniqueCount = 0; for (int i = 0; i < _count; i++) { bool exists = false; for (int j = 0; j < uniqueCount; j++) { if (comparer.Equals(_items[i], uniqueItems[j])) { exists = true; break; } } if (!exists) { uniqueItems[uniqueCount] = _items[i]; uniqueCount++; } } _items = uniqueItems; _count = uniqueCount; } public IEnumerator GetEnumerator() { for (int i = 0; i < _count; i++) { yield return _items[i]; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } private void ValidateIndex(int index) { if (index < 0 || index >= _count) { throw new IndexOutOfRangeException("Индекс находится вне границ списка."); } } private void ValidateInsertIndex(int index) { if (index < 0 || index > _count) { throw new IndexOutOfRangeException("Индекс для вставки находится вне границ списка."); } } private void EnsureCapacityFor(int additionalItems) { while (_count + additionalItems > _items.Length) { int newCapacity = _items.Length == 0 ? DefaultCapacity : _items.Length * 2; Array.Resize(ref _items, newCapacity); } } private static MyList CreateSafeCopy(MyList source) { MyList copy = new MyList(Math.Max(DefaultCapacity, source.Count)); foreach (T item in source) { copy.Add(item); } return copy; } } }