繁体   English   中英

使用最少的资源在布尔数组中查找特定元素 C#

[英]Find a specific element in an array of Booleans while using the least amount of resources C#

我有一个假设的布尔数组,其中包含 50 个元素。 这些布尔值的值对我来说是未知的,找出特定元素值的唯一方法是调用一个方法并为其提供元素的索引。 这种方法在 CPU 周期方面成本很高,我想做的是编写一个代码,使用最少的调用此方法来确定特定元素的值。

如果此数组中有一个值为假的元素,则它之前的所有元素也必须为假。 如果这个数组中有一个值为真的元素,那么它后面的所有元素也必须为真。

举个这样的arrays的例子:

[false, false, false, true, true, true, true]
[false, false, false, false]
[true, true]

正如您所猜到的,我正在寻找的元素是发生从 false 到 true 变化的元素(如果有的话)。

显然,我首先想到的是稍微修改一下的二进制搜索,如下所示:

int FindFirstTrue(HypotheticalBool[] arr)
{
    int low = 0;
    int high = arr.Length - 1;
    int mid;
    while (low <= high)
    {
        mid = low + (high - low) / 2;
        if (checkArr(arr, mid))
        {
            if (!checkArr(arr, mid-1))
            {
                return mid;
            }
            else
            {
                high = mid - 1;
            }
        }
        else
        {
            low = mid + 1;
        }
    }
    return -1; 
}

checkArr(HypotheticalBool[] arr, int elementIndex)是我上面提到的 CPU 饥饿方法。 在最坏的情况下,此代码需要 11 次调用checkArr()才能找到正确的元素。

我想做的是降低这个数字。 是否有更有效的二分搜索实现来实现这个目标?

在尝试运行您的算法时,我遇到了 IndexOutOfRangeException。 我不得不将第二个 if 语句更改为if (mid < 1 ||,CheckArr(arr, mid - 1))

为了简化操作,我使用了一个真正的 Boolean 数组,并在数组检查方法中添加了一个计数器。 然后我通过用 0 到 50 个false值填充数组并用true值填充 rest 来重复搜索。 FindFirstTrue方法的平均计数为7.68 ,计数范围为 2.. 11(含)。

这可以改进,因为您调用checkArr两次。 这是我的实现:

static int FindFirstTrue(bool[] arr)
{
    int low = 0;
    int high = arr.Length - 1;
    int mid = 0;
    bool lastCheck = false;
    while (low <= high) {
        mid = (low + high) / 2;
        lastCheck = CheckArr(arr, mid);
        if (lastCheck) {
            high = mid - 1;
        } else {
            low = mid + 1;
        }
    }
    if (!lastCheck) {
        mid++;
    }
    return low < arr.Length ? mid : -1;
}

平均计数为5.86 ,计数范围为 5.. 6(含)。 这减少了 23.7%。

二分查找的理论计数为 log 2 (50) ≈ 5.64。 因此,5.86 非常接近最佳值。

但根据您的实际阵列的性质,这可以改进。 例如,如果您有一个近似于已知 function 的数字范围,那么该问题可以转化为根搜索问题。 对于这类问题,有比二分查找更好的算法。 另见寻根算法

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM