确定2D数组是否包含元素的最快方法?

时间:2009-11-01 14:12:56

标签: c# algorithm

我们假设我有二维数组,如:

int[,] my_array = new int[100, 100];

数组中填充了整数。检查数组中是否包含目标值元素的最快方法是什么?

(*这不是功课,我正试图为这种情况提出最有效的解决方案)

4 个答案:

答案 0 :(得分:15)

如果数组没有以某种方式排序,我看不出有什么比使用两个for语句检查每个值更快的方法。如果它已排序,您可以使用二进制搜索。

编辑: 如果您需要反复执行此操作,您的方法将取决于数据。如果此数组中的整数范围最多为256,则可以使用该长度的布尔数组,并浏览数据中的值,并翻转布尔数组中的位。如果整数可以更高,则可以使用HashSet。对contains函数的第一次调用会有点慢,因为它必须索引数据。但随后的电话会是O(1)。

EDIT1:

这将在第一次运行时索引数据,基准测试发现Contains在第一次运行后运行需要0毫秒,13运行到索引。如果我有更多的时间,我可能多线程并让它返回结果,同时在第一次调用时异步继续索引。此外,由于数组是引用类型,因此更改在索引之前或之后传递的数据的值将提供奇怪的功能,因此这只是一个示例,应该在使用之前进行重构。

private class DataContainer
{
    private readonly int[,] _data;
    private HashSet<int> _index;

    public DataContainer(int[,] data)
    {
        _data = data;
    }

    public bool Contains(int value)
    {

        if (_index == null)
        {
            _index = new HashSet<int>();
            for (int i = 0; i < _data.GetLength(0); i++)
            {
                for (int j = 0; j < _data.GetLength(1); j++)
                {
                    _index.Add(_data[i, j]);
                }
            }
        }
        return _index.Contains(value);
    }
}

答案 1 :(得分:1)

从2d数组中创建一个哈希值,其中

1 - &gt;第一排 2 - &gt;第二排 ... n - &gt;第n行

O(n)检查给定元素是否存在,假设每个散列检查给出O(1)。

此数据结构为您提供了保留二维数组的机会。

upd:忽略上面的内容,它不会给出任何值。见评论

答案 2 :(得分:1)

假设:

  • 我们可以利用
  • 在阵列中没有任何排序
  • 您将多次检查数组中是否存在

我认为某种索引可能效果很好。如果给定数字在数组中,则需要是/否答案。可以使用哈希表,为查找提供常量O(k)。

另外,请不要忘记,对于小的MxN阵列大小,实际上进行线性O(n)查找实际上可能更快。

答案 3 :(得分:0)

您可以封装数据本身,并保留一个字典以及随着数据被修改而被修改的字典。

Dictionary的键是目标元素值,值将是元素的条目数。要测试元素是否存在,只需检查字典中的计数&gt; 0,介于O(1)和O(n)之间。您还可以使用此构造更快地获得有关数据的其他统计信息,尤其是在数据稀疏的情况下。

此解决方案的最大缺点是数据修改涉及更多操作(但仍应为O(1)),因此如果您主要进行数据操作,那么这可能不合适。