在排序向量中找到最近的索引

kir*_*off -1 c++ algorithm optimization performance intel-vtune

我编写了一个C++例程来查找排序数组中最近的double元素.有没有办法加快?

reversed如果reversed按降序排序,则有两个基于boolean值的分支.

 void findNearestNeighbourIndex_new(real_T value, real_T* x, int_T x_size, int_T& l_idx)
{
    l_idx = -1;

    bool reversed= (x[1] - x[0] < 0);

    if ((!reversed&& value <= x[0]) 
                  || (reversed&& value >= x[0])){ 
        // Value is before first position in x
        l_idx = 0;
    }
    else if ((!reversed&& value >= x[x_size - 1]) 
                    || (reversed&& value <= x[x_size - 1])){ 
        // Value is after last position in x
        l_idx = x_size - 2;
    }
    else // All other cases
    {
        if (reversed)
        {
            for (int i = 0; i < x_size - 1; ++i)
            {
                if (value <= x[i] && value > x[i + 1])
                {
                    l_idx = i;
                    break;
                }
            }
        }
        else{
            for (int i = 0; i < x_size - 1; ++i)  
            {
                if (value >= x[i] && value < x[i + 1])
                {
                    l_idx = i;
                    break;
                }
            }
        }   
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种排序数组的情况下,我没有办法做得更好.因此,通过分析,我发现比较if (value <= x[i] && value > x[i + 1])是昂贵的.

编辑

尝试使用lower_bound()

std::vector<real_T> x_vec(x, x + x_size);

l_idx = std::upper_bound(x_vec.begin(), x_vec.end(), value) - x_vec.begin() - 1;
Run Code Online (Sandbox Code Playgroud)

PSI*_*Alt 10

您可以使用std :: lower_bound查找等于或大于请求的元素,然后向后移动迭代器并检查前面的值.这将使用二进制搜索并且将花费O(log n),这也使得标准STL比较器等等.

  • @octoback因为你正在使用迭代器和它的std :: vector - 你可以很容易地做迭代器matematics(减法向量开始迭代器来获取索引). (2认同)