我有这个函数,该函数应该计算在某个数组中出现多少个相同编号的重复项。重要的是,它必须具有复杂度O(logn)。 我在下面写下了这个,但是它没有正确地计算出重复项。 还有一件事,数字从最低到最高排序。
int CountElementsinFile(int *Arr, int num, int numOfD)
{
int avg{};
int inB = 0;
int inE = numOfD - 1;
int el{};
while (inB <= inE)
{
avg = (inB + inE) / 2;
if (Arr[avg] == num)
el++;
if (Arr[avg] > num)
inE = avg - 1;
else
inB = avg + 1;
}
return el;
}
答案 0 :(得分:2)
使用std,您可以这样做:
int CountElementsinFile(const int *a, int size, int value)
{
const auto range = std::equal_range(a, a + size, value);
return range.second - range.first;
}
答案 1 :(得分:2)
您需要使用Bisection method确定num
子序列的上下边界。您需要在while循环中重新排列搜索区域的上下边界(取决于比较),直到inB < inE
将区域缩小一半。复杂度将为O(ln(n))
。您已经接近了,但是您无法在一个while
循环中找到两个边界。我刚刚更正了您的代码。
int CountElementsinFile(int *Arr, int num, int numOfD)
{
// There is no num in the array
if (Arr[0] > num || Arr[numOfD - 1] < num)
return 0;
int avg{};
int lb, ub;
// Find lower boundary
int inB = 0;
int inE = numOfD - 1;
while (inB < inE)
{
// divide search region
avg = (inB + inE) / 2;
if (Arr[avg] >= num)
inE = avg;
else
inB = avg+1;
}
lb = inE;
// Find upper boundary
// inB already found
inE = numOfD - 1;
while (inB < inE)
{
avg = (inB + inE + 1) / 2;
if (Arr[avg] > num)
inE = avg-1;
else
inB = avg;
}
ub = inB;
return ub - lb + 1;
}
int main()
{
int arr[] = { 5, 7, 8, 9, 9, 9, 9, 9, 11 };
std::cout << CountElementsinFile(arr, 9, sizeof(arr) / sizeof(int)) << std::endl;
return 0;
}
答案 2 :(得分:0)
从您提供的函数签名中,我猜您将得到一个数字N和一个排序的数字数组,并且需要计算N在数组中出现的次数。
由于对数组进行了排序,因此需要找到小于N的第一个数字(这是O(log n)
)的索引(使用二进制搜索),大于N的第一个数字的索引(这里是{也为O(log n)
),只需将一个索引与另一个索引相减即可。
当然,您需要考虑边缘情况,即没有小于N的数字或小于N的数字,但这是您要找出的。
答案 3 :(得分:0)
#include<algorithm>
using namespace std;
int CountElementsinFile(int arr[], int size, int numToSearch)
{
return count(arr, arr + size, numToSearch);
}