71 lines
2.5 KiB
C#
71 lines
2.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
|
|
namespace DTLib
|
|
{
|
|
public class CompressedArray
|
|
{
|
|
public class Array1D<T> where T : IComparable<T>
|
|
{
|
|
byte[] Description;
|
|
T[] Memory;
|
|
|
|
public Array1D() { }
|
|
public Array1D(T[] sourceArray) => CompressArray(sourceArray);
|
|
|
|
public void CompressArray(T[] sourceArray)
|
|
{
|
|
List<T> listMem = new List<T>();
|
|
List<byte> listDesc = new List<byte>();
|
|
T prevElement = sourceArray[0];
|
|
listMem.Add(sourceArray[0]);
|
|
listDesc.Add(1);
|
|
byte repeats = 1;
|
|
for (int i = 1; i < sourceArray.Length; i++)
|
|
{
|
|
if (prevElement.CompareTo(sourceArray[i]) == 0)
|
|
repeats++;
|
|
else
|
|
{
|
|
listMem.Add(sourceArray[i]);
|
|
listDesc.Add(1);
|
|
if (repeats > 1)
|
|
{
|
|
listDesc[listDesc.Count - 2] = repeats;
|
|
repeats = 1;
|
|
}
|
|
}
|
|
prevElement = sourceArray[i];
|
|
}
|
|
Memory = listMem.ToArray();
|
|
Description = listDesc.ToArray();
|
|
ColoredConsole.Write("b", "listMem.Count: ", "c", listMem.Count.ToString(), "b", " listDesc.Count: ", "c", listDesc.Count + "\n");
|
|
for (short i = 0; i < listDesc.Count; i++)
|
|
{
|
|
ColoredConsole.Write("y", $"{Description[i]}:{Memory[i]}\n");
|
|
}
|
|
}
|
|
|
|
// блокирует обращение к памяти из нескольких потоков
|
|
Mutex storageUsing = new();
|
|
|
|
// возвращает элемент по индексу так, как если бы шло обращение к обычном массиву
|
|
public T GetElement(int index)
|
|
{
|
|
storageUsing.WaitOne();
|
|
T output = default;
|
|
int sum = 0;
|
|
for (int i = 0; i < Description.Length; i++)
|
|
{
|
|
if (sum < index)
|
|
sum += Description[i];
|
|
else output = sum == index ? Memory[i] : Memory[i - 1];
|
|
}
|
|
storageUsing.ReleaseMutex();
|
|
return output;
|
|
}
|
|
}
|
|
}
|
|
}
|