Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 查找数组中第一次出现偶数的索引,运行时成本为O(log(n))_C++_Arrays_Algorithm_Time Complexity - Fatal编程技术网

C++ 查找数组中第一次出现偶数的索引,运行时成本为O(log(n))

C++ 查找数组中第一次出现偶数的索引,运行时成本为O(log(n)),c++,arrays,algorithm,time-complexity,C++,Arrays,Algorithm,Time Complexity,我必须实现一个算法,运行时成本为O(log(n)),该算法在具有以下属性的数组中查找偶数的第一次出现: 数组的第一个元素是奇数,接下来的元素是偶数 我不知道有多少元素是奇数,有多少元素是偶数,但我知道至少有一个偶数和一个奇数 我已经写了这个“代码草案”,但工作不正常,有什么改进的建议吗?我认为这个解决方案与我的(我希望)没有太大的不同。 #包括 使用名称空间std; int minInd=1000; 整数f(整数v[],整数开始,整数结束) { int m=结束/2; 如果(v[开始]%2=

我必须实现一个算法,运行时成本为O(log(n)),该算法在具有以下属性的数组中查找偶数的第一次出现:

  • 数组的第一个元素是奇数,接下来的元素是偶数
  • 我不知道有多少元素是奇数,有多少元素是偶数,但我知道至少有一个偶数和一个奇数
我已经写了这个“代码草案”,但工作不正常,有什么改进的建议吗?我认为这个解决方案与我的(我希望)

没有太大的不同。
#包括
使用名称空间std;
int minInd=1000;
整数f(整数v[],整数开始,整数结束)
{
int m=结束/2;
如果(v[开始]%2==0)
如果(开始<最小值)
minInd=开始;
f(v,开始,m);
f(v,m+1,结束);
返回minInd;
}
int main()
{
int v[]={1,3,7,9,5,4,6,8};
int指数=f(v,0,7);

cout您遇到的问题是,您在没有条件的情况下运行了两次
f
方法。此外,您的条件应该是检查当前正在处理的给定子数组中间的奇偶校验

你应该这样做:

int f(int v[], int start, int end)
{
    int m = (start + end)/2;


    if(v[m]%2 == 0) {
        if(start == end) { 
            return start;
        } else {
            return f(v, start, m);
        }
    } else {
        return f(v, m, end);
    }
}
(我没有在这里检查边缘情况等。只是粗略了解逻辑)


@marek-r更新了以下评论有几个问题:

您没有递归的终止条件。
您递归到数组的两半部分,即使添加了终止,也会破坏日志复杂性。
你的细分方法是神秘的,你应该看看中间的元素,然后选择其中的一半。 全局和递归是一种特别令人不快的组合

这是一个常规的二进制搜索,最后有一个小的转折-它首先递归,然后做出决定

int f(int v[], int start, int end)
{
    // Terminate when nothing is left.
    if (start >= end)
        return -1;
    // Look at the midpoint.
    int mid = start + (end-start) / 2;
    // If it's odd, the first even number is to the right.
    if (v[mid] % 2 != 0)
    {
        return f(v, mid + 1, end);
    }
    // Otherwise, first see if there is any even number to the left.
    int left = f(v, start, mid);
    // And choose a result depending on whether there was.
    return left == -1 ? mid : left; 
}
请注意,这使用了传统的半开间隔。

size\u t先查找\u偶数(const int v[],int size)
{
返回标准::距离(v,标准::下限(v,v+size,0,
[](自动a,自动b){返回a&1>b&1;});
}

您有一个包含两个分区的数组,奇数值后跟偶数值。标准库算法正是您需要在O(logn)时间内找到第二个分区开始的函数


这段代码基于,我只是认为更多的人应该知道这个稍微模糊的库算法。

这是一个简单的二进制搜索问题std::binary_search@ServeLaurijssen不幸的是,
std::binary_search
是无用的,因为它返回的是
bool
而不是迭代器。此代码不是
O(log n)
这个不定式递归。所以基本上你有一个上帝的想法,但你以错误的方式实现了它。请解释“工作不正常”。@MarekR-谢谢。我认为顶层变量是作为解决方案打印出来的。修复了。
int f(int v[], int start, int end)
{
    // Terminate when nothing is left.
    if (start >= end)
        return -1;
    // Look at the midpoint.
    int mid = start + (end-start) / 2;
    // If it's odd, the first even number is to the right.
    if (v[mid] % 2 != 0)
    {
        return f(v, mid + 1, end);
    }
    // Otherwise, first see if there is any even number to the left.
    int left = f(v, start, mid);
    // And choose a result depending on whether there was.
    return left == -1 ? mid : left; 
}
size_t find_first_even(const int *v, int size)
{
    auto itr = std::partition_point(v, v + size, [](int value) { return value & 1; });
    return std::distance(v, itr);
}