
[英]C# - How to find the most common and the least common integers in an array?
[英]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.