是否有一种更有效的方法来执行此算法

Is there a more efficient way to do this algorithm?

本文关键字:方法 执行 算法 有效 一种 是否      更新时间:2023-10-16

据我所知,该算法将正确搜索并在需要时变为true。在课堂上,我们正在谈论大O分析,因此此任务是展示递归搜索如何比迭代搜索更快。关键是要搜索一个数字,以便a [i] = i(找到与存储在索引上的数字相同的索引)。该算法与迭代算法仅相差约100纳秒,但有时迭代速度更快。我使用rand()函数在main中设置了向量。我运行了两次算法并记录时代。我问的问题是,这种算法效率尽可能高,还是有更好的方法?

bool recursiveSearch(vector<int> &myList, int beginning, int end)
{
    int mid = (beginning + end) / 2;
    if (myList[beginning] == beginning) //check if the vector at "beginning" is
    {                                      //equal to the value of "beginning"
        return true;
    }
    else if (beginning == end) //when this is true, the recursive loop ends.
    {                          //when passed into the method: end = size - 1
        return false;
    }
    else
    {
        return (recursiveSearch(myList, beginning, mid) || recursiveSearch(myList, mid + 1, end));
    }
}

编辑:该列表是在通过之前预订的,并在主要进行检查之前,以确保启动和终点都存在

一种可能的"改进"将是不通过参考来复制每个递归中的向量:

bool recursiveSearch(const vector<int>& myList, int beginning, int end)

,除非您知道有关数据订购的一些特别之处,否则执行这样的分区搜索绝对没有优势。

的确,您的代码实际上是[尝试]进行线性搜索,因此它实际上正在实现一个简单的循环,其成本是许多堆栈和开销。

请注意,您的代码中有一个奇怪的信息:如果第一个元素不匹配,则会调用recursiveSearch(myList, beginning /*=0*/, mid)。由于我们已经知道元素0不匹配,因此您将再次进行细分,但仅在重新测试元素之后。

因此,给定6个没有匹配的元素的向量,您将致电:

recursiveSearch(mylist,0,6); ->&lt;corursivesearch(mylist,0,3)||corsursivesearch(MyList,4,6);> ->&lt;corsursivesearch(mylist,0,1)||soursivesearch(2,3)>&lt;corsursivesearch(MyList,4,5);||corsursivesearch(MyList,5,6);> ->&lt;corursivesearch(mylist,0,0)||recursiveSearch(mylist,1,1)>&lt;corursivesearch(mylist,2,2)||corursivesearch(mylist,3,3)> ...

最终,您在给定索引上失败了,因为您达到了一个值得一开始的情况,这似乎是一种消除每个节点的昂贵方法,而最终结果不是分区的搜索,这是一个简单的线性搜索,您只需使用很多堆栈深度即可到达那里。

因此,这样做的一种更简单,更快的方法是:

for (size_t i = beginning; i < end; ++i) {
    if (myList[i] != i)
        continue;
    return i;
}

由于我们正在尝试在此处进行优化,因此值得指出的是,MSVC,GCC和Clang都假定if表达了可能的情况,因此我在此处对我们有一个没有或没有或没有的大型向量的情况进行优化晚比赛。在我们很幸运的情况下,我们发现结果很早,那么我们愿意支付潜在分支机构的费用,因为我们要离开。我意识到分支缓存很快将为我们弄清楚,但是再次优化; p

正如其他人指出的那样,您也可以从不通过价值传递向量(强制副本)

中受益
const std::vector<int>& myList

一个明显的"改进"是在所有剩余内核上运行线程。只需将vector划分为number of cores - 1件,然后使用条件变量在发现时发出信号。

如果您需要在未排序的数组中找到一个元素,以便 A[i] == i,那么唯一的方法是遍历每个元素,直到找到一个元素。

最简单的方法就是这样:

bool find_index_matching_value(const std::vector<int>& v)
{
    for (int i=0; i < v.size(); i++) {
        if (v[i] == i)
            return true;
    }
    return false; // no such element
}

这是O(n),您将无法比该算法更好。因此,我们必须将注意力转移到微观上。

通常,如果在现代机器上,您的递归解决方案通常比上面的简单解决方案要快。虽然编译器(可能)可以删除额外的功能调用开销(有效地将递归解决方案变成迭代的解决方案),但通过数组(如上所述)允许最佳使用缓存,而对于大型大型使用数组,您的分区搜索不会。