1
0
Files
Debug_pro d47bde6c27 upload
2026-06-07 18:27:45 +03:00

359 lines
9.1 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Prac8
{
public class MyList<T> : IEnumerable<T>
{
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<T> otherList)
{
if (otherList == null)
{
throw new ArgumentNullException(nameof(otherList), "Другой список не должен быть null.");
}
MyList<T> source = CreateSafeCopy(otherList);
EnsureCapacityFor(source.Count);
foreach (T item in source)
{
Add(item);
}
}
public void InsertRange(int index, MyList<T> otherList)
{
ValidateInsertIndex(index);
if (otherList == null)
{
throw new ArgumentNullException(nameof(otherList), "Другой список не должен быть null.");
}
if (otherList.Count == 0)
{
return;
}
MyList<T> 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<T> 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<T> comparer = Comparer<T>.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<T> comparer = EqualityComparer<T>.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<T> 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<T> CreateSafeCopy(MyList<T> source)
{
MyList<T> copy = new MyList<T>(Math.Max(DefaultCapacity, source.Count));
foreach (T item in source)
{
copy.Add(item);
}
return copy;
}
}
}