You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中高效向集合添加数值范围仅替换null元素的实现方案

实现需求的.NET内置结构方案

完全可以用.NET内置数据结构实现这个AddRange方法,核心是通过预跟踪空位索引避免遍历集合查找空位,同时用数组存储元素保证直接访问。以下是两种适配不同场景的实现方案:

方案1:按空位顺序填充(无需连续空位)

适合不要求添加的元素必须放在连续位置的场景,用Queue<int>存储所有空位的索引,初始化时将集合的所有索引入队,添加元素时直接从队列取出空位赋值,全程无需遍历集合找空位。

代码实现

public class NullReplaceableCollection<T> where T : struct
{
    private readonly T?[] _elements;
    private readonly Queue<int> _emptySlotIndices;

    // 初始化指定容量的空集合
    public NullReplaceableCollection(int capacity)
    {
        _elements = new T?[capacity];
        _emptySlotIndices = new Queue<int>(Enumerable.Range(0, capacity));
    }

    public bool AddRange(T[] values)
    {
        if (values == null || values.Length == 0)
            return false;

        // 空位不足直接返回false
        if (_emptySlotIndices.Count < values.Length)
            return false;

        // 依次取出空位填充元素
        for (int i = 0; i < values.Length; i++)
        {
            int slotIndex = _emptySlotIndices.Dequeue();
            _elements[slotIndex] = values[i];
        }

        return true;
    }

    // 辅助方法:获取当前集合的副本
    public T?[] GetCurrentState() => (T?[])_elements.Clone();
}

测试示例

  • 初始化容量为6的集合,GetCurrentState()返回{null,null,null,null,null,null}
  • 调用AddRange(new int[]{2,3,4}),返回true,集合变为{2,3,4,null,null,null}
  • 再调用AddRange(new int[]{0,1,5}),返回true,集合被填满
  • 调用AddRange(new int[]{4,5}),因无空位返回false

方案2:强制连续空位填充

如果要求添加的元素必须放在连续的空位区间(匹配你示例中填充中间三个空位的场景),可以用SortedSet<int>存储空位索引,利用其有序性快速查找连续的空位区间,同样无需遍历整个集合。

代码实现

public class ContinuousNullReplaceableCollection<T> where T : struct
{
    private readonly T?[] _elements;
    private readonly SortedSet<int> _emptySlotIndices;

    public ContinuousNullReplaceableCollection(int capacity)
    {
        _elements = new T?[capacity];
        _emptySlotIndices = new SortedSet<int>(Enumerable.Range(0, capacity));
    }

    public bool AddRange(T[] values)
    {
        if (values == null || values.Length == 0)
            return false;

        int requiredSlots = values.Length;
        if (_emptySlotIndices.Count < requiredSlots)
            return false;

        // 查找连续的requiredSlots个空位
        int? startSlot = null;
        foreach (var slot in _emptySlotIndices)
        {
            bool hasConsecutive = true;
            for (int i = 1; i < requiredSlots; i++)
            {
                if (!_emptySlotIndices.Contains(slot + i))
                {
                    hasConsecutive = false;
                    break;
                }
            }
            if (hasConsecutive)
            {
                startSlot = slot;
                break;
            }
        }

        // 找不到连续空位则返回false
        if (startSlot == null)
            return false;

        // 填充连续空位
        for (int i = 0; i < requiredSlots; i++)
        {
            int slotIndex = startSlot.Value + i;
            _emptySlotIndices.Remove(slotIndex);
            _elements[slotIndex] = values[i];
        }

        return true;
    }

    public T?[] GetCurrentState() => (T?[])_elements.Clone();
}

关键优势

两种方案都完全避免了遍历集合查找空位的操作:

  • Queue<int>直接缓存所有空位索引,取用时O(1)
  • SortedSet<int>利用有序性快速定位连续区间,无需遍历整个集合
  • 所有操作都是基于数组的直接索引访问,性能高效

内容的提问来源于stack exchange,提问作者user1423893

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 23:00:57