【问题标题】:Simpler method for pooling integers合并整数的更简单方法
【发布时间】:2013-10-20 19:14:23
【问题描述】:

我希望能够根据数组的可用性从数组中获取整数。当一个可用的整数被选中时,它会变得不可用,直到它被返回。

虽然这遵循了一个简单的池想法,但我认为我的方法过于复杂,希望得到一些建议。

我正在实现许多类似于池的关键功能,包括:

  • 获取第一个可用的最小整数
  • 按升序获取所有可用整数
  • 从数组中获取特定整数
  • 将特定整数返回给数组以使其再次可用

对于第一种方法,我通过每次成功调用整数请求时递增一个值来记录可用整数。如果可用整数按其 .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; }
    }
}

这让我觉得我把这个问题弄得太复杂了,并且有一种更优雅的方法可以解决这个问题。有什么建议吗?

【问题讨论】:

  • 整数是连续的吗?也就是说,数组是否以 0、1、2、3、4、5、6 等开始填充?还是像 2、6、26、256 等一样稀疏?
  • 必须是数组吗?还有其他结构可以更轻松地获得您想要的结果...
  • @Micah 目前是连续的。
  • @PatrykĆwiek 它不一定是一个数组。
  • @user1423893 没错。如果它适用于您的特定情况,它将大大简化整个方法。

标签: c# arrays sorting integer


【解决方案1】:
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;
        }
    }
}

【讨论】:

  • 欢迎来到社区@Izikon。而不是发布另一个答案,只需编辑您当前的答案并在那里添加您的代码。我还建议您查看 stackoverflow 的 about 和 faq 部分。
  • 这看起来也像是另一条下坡路。谢谢你,Izikon。
  • 我对这个回复有几个问题:1) 它通过 GetAll 方法公开了 _integers 字段。 2) Get 方法不会从 _integers 中删除请求的整数。 3)应该调用 Add 方法,例如初始化,因为它不添加任何东西;它重置 _sourceIntegers 以及汇集的整数。 (实际上,我更愿意在构造函数中提供源整数。) 4) _sourceintegers.Select(p => p).ToList() 的 Select(p => p) 部分似乎有点不必要。 5)它不编译...
  • 已编辑,忘记 ")" 并删除。 spacedoom 为你的言论。 1)这是它需要做的。 2)现在可以了。 3) 它添加整数列表 4) select 部分正在克隆列表 5) 编译和测试
  • 我将把它标记为答案。经过一些急需的睡眠后,我设计了一个非常简单的 List 方法。这可以非常快速地处理整数的升序,而不需要花哨的排序算法。我可以发布这是有人感兴趣的。
【解决方案2】:

为什么不克隆一个简单的整数数组,然后在每个循环中提取第一项并重新使用克隆的数组?

【讨论】:

    【解决方案3】:

    我会从这样的东西开始,然后如果您发现性能有问题,请对其进行优化。根据您的整数集合的大小,这可能是一个非常快速的解决方案(对于相对较小的集合大小)或非常慢的解决方案(对于非常大的集合大小)。

    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;
                }
            }
        }
    }
    

    【讨论】:

    • 这是一个可行的解决方案。我写了类似的东西,但不想实现它,因为它似乎是一种蛮力类型的方法。
    猜你喜欢
    • 2016-12-12
    • 2012-02-27
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 2014-12-24
    • 2015-11-07
    相关资源
    最近更新 更多