Более простой метод для объединения целых чисел
Я хотел бы иметь возможность брать целые числа из массива в зависимости от их доступности. Когда выбрано доступное целое число, оно становится недоступным, пока не будет возвращено.
Хотя это следует простой идее пула, я думаю, что я слишком усложнил свой подход и хотел бы получить несколько советов.
Я реализую ряд ключевых функций, подобных пулу, в том числе:
- Получить первое доступное наименьшее целое число
- Получить все доступные целые числа в порядке возрастания
- Получить конкретное целое число из массива
- Вернуть массиву конкретное целое число, чтобы снова сделать его доступным
Для первого метода я веду подсчет доступных целых чисел, увеличивая значение каждый раз, когда запрос целого числа успешно вызывается. Затем это значение можно использовать для определения начального индекса для доступных целых чисел, если они будут отсортированы по их логическому значению.IsAvailable.
public static int GetInteger()
{
// Get the next available integer
int startIndex = integers.Length - numAvailableIntegers;
var c = integers[startIndex];
c.IsAvailable = false;
// Sort the integers by availability
Array.Sort(integers, SortIntegerAvailability.Comparer);
numAvailableIntegers--;
return c.Value;
}
Проблема здесь в том, что сортировка по логическому значению также требует сортировки по возрастанию целочисленного значения впоследствии.
class SortIntegerAvailability : IComparer<Integer>
{
static IComparer<Integer> comparer = new SortIntegerAvailability();
public int Compare(Integer a, Integer b)
{
if (a.IsAvailable == b.IsAvailable)
{
return 0;
}
else return (a.IsAvailable == true) ? 1 : -1;
}
public static IComparer<Integer> Comparer
{
get { return comparer; }
}
}
Это привело меня к мысли, что я делаю это слишком сложным и что есть более элегантный подход к этой проблеме. Какие-либо предложения?
3 ответа
class IntegersGame
{
private List<int> _sourceintegers;
private List<int> _integers;
public void Add(List<int> integers)
{
_sourceintegers = integers;
Reset();
}
public void Reset()
{
_integers = _sourceintegers.Select(p => p).ToList();
_integers.Sort();
}
public int GetFirst()
{
int ret = _integers.First();
_integers.Remove(ret);
return ret;
}
public List<int> GetAll()
{
return _integers;
}
public void Release(int des)
{
if (_sourceintegers.Contains(des))
{
_integers.Add(des);
_integers.Sort();
}
}
public int? Get(int source)
{
if(_sourceintegers.Contains(source) && (_integers.Contains(source))){
_integers.Remove(source);
return source;
}else{
return null;
}
}
}
Почему бы просто не клонировать простой целочисленный массив, извлечь первый элемент и применить клонированный массив каждый цикл?
Я бы начал с чего-то вроде этого, а затем оптимизировал бы его, если бы вы столкнулись с проблемой производительности. В зависимости от размера вашей целочисленной коллекции, это может быть очень быстрое решение (для относительно небольших размеров коллекции) или очень медленное (для невероятно больших размеров коллекции).
private class MyInteger
{
public int Value;
public bool Available;
public void MyInteger(int value, bool available)
{
Value = value;
Available = available;
}
}
public class IntegerPool
{
private IList<MyInteger> _integers = new List<MyInteger>();
public void IntegerPool(List<int> startingCollection)
{
startingCollection.Sort();
foreach (var integer in startingCollection)
{
_integers.Add(new MyInteger(integer, true));
}
}
public int GetFirstAvailable()
{
foreach (var integer in _integers)
{
if (integer.Available)
{
integer.Available = false;
return integer.Value;
}
}
throw new Exception("No more integers available.");
}
public IList<int> GetAllAvailable()
{
var list = new List<int>();
foreach (var integer in _integers)
{
if (integer.Available)
list.Add(integer.Value);
}
return list;
}
public int? TryGetSpecific(int specific)
{
foreach (var integer in _integers)
{
if (integer.Value == specific)
{
if (!integer.Available)
return null;
integer.Available = false;
return integer.Value;
}
}
throw new Exception("Integer not in collection.");
}
public void ReleaseInteger(int integerToBeReleased)
{
foreach (var integer in _integers)
{
if (integer.Value == integerToBeReleased)
{
integer.Available = true;
return;
}
}
}
}