【问题标题】:c++ code: about sorted search test samplec++代码:关于排序搜索测试样本
【发布时间】:2017-06-22 13:08:35
【问题描述】:

我正在为 testdome https://www.testdome.com/for-developers/solve-question/9880 中给出的测试样本写答案

问题是关于排序搜索的: 实现函数 countNumbers,它接受整数的排序向量并计算小于参数 lessThan 的向量元素的数量。

例如,对于包含 { 1, 3, 5, 7 } 的向量 v,SortedSearch::countNumbers(v, 4) 应该返回 2,因为有两个向量元素小于 4。

我修改代码如下,但测试结果显示有两个失败: 1)sortedVector包含lessThan时的性能测试:超过时间限制 2)sortedVector不包含lessThan时的性能测试:超过时间限制

您能帮忙更新我的代码以解决问题吗?

#include <vector>
#include <stdexcept>
#include <iostream>

class SortedSearch
{
public:
    static int countNumbers(const std::vector<int>& sortedVector, int lessThan)
    {
        int a = 0;
        for (size_t i=0; i<sortedVector.size(); i++)
        {
            if (sortedVector[i]<lessThan)
            {
                a++;
            }
        }
        return a;
    }
};

#ifndef RunTests
int main()
{
    std::vector<int> v { 1, 3, 5, 7 };
    std::cout << SortedSearch::countNumbers(v, 4);
}
#endif

【问题讨论】:

    标签: c++


    【解决方案1】:

    您可以利用对数据进行排序这一事实在对数时间内找到答案。 C++ 标准库有一个算法来完成这个任务。

    使用std::lower_bound 查找大于或等于您的目标值的第一个元素。然后调用std::distance返回从容器开始到上一步找到的位置的元素计数。

    #include <algorithm>
    #include <iterator>
    
    class SortedSearch
    {
    public:
        static int countNumbers(const std::vector<int>& sortedVector, int lessThan)
        {
            // get an iterator to the first element >= lessThan
            auto itr = std::lower_bound(std::begin(sortedVector), std::end(sortedVector), lessThan); // O(log n)
    
            // return the distance between two iterators
            return std::distance(std::begin(sortedVector), itr); // O(1)
        }
    };
    

    【讨论】:

    • @Slava 我可以指定命名空间,但可以通过参数相关查找 (ADL) 找到它们。也许我会更明确地编辑答案。
    • 感谢 Blastfurnace,据我了解,问题是要计算有多少向量成员小于 tan 参数 lessThan。我无法理解您的代码如何达到结果。能详细解释一下吗?
    • @LeiWang std::lower_bound 将迭代器返回到不小于(即大于或等于)目标值的第一个元素。小于目标的元素个数是返回的迭代器的偏移量和容器的开头。这就是 std::distance 调用返回的内容。
    • @LeiWang 请注意,此算法具有对数运行时间,因此它可以有效地进行二进制搜索。我在您链接的网站上测试了这段代码,它通过了测试。
    • 谢谢。不小于目标值的第二个元素怎么样?我是否需要对整个向量成员重复使用此方法,或者只在您提供的时候调用这些函数一次。似乎 std::distance 只返回从开始到小于目标的第一个元素的偏移量......
    【解决方案2】:

    尝试使用更快的方法。使用 binary_search 查找小于给定元素的最后一个元素。

    【讨论】:

    • 这个答案是指标准库中的std::binary_search 吗?该函数返回一个bool,所以我不确定它在这里有什么用处。
    【解决方案3】:

    实际上已经在 Wiki: Binary Search algorithm 中实现了。 在“寻找最左边元素的过程”中寻找解释和实现。

    这是我的答案:

    #include <vector>
    #include <stdexcept>
    #include <iostream>
    
    class SortedSearch
    {
    public:
        static int countNumbers(const std::vector<int>& sortedVector, int lessThan)
        {
            int lower, upper, middle;
    
            lower = 0;
            upper = sortedVector.size();
    
            // do a binary search
            while(lower < upper)
            {
                middle = (lower + upper) / 2;
    
                if (sortedVector[middle] < lessThan)
                {
                    lower = middle + 1;
                }
                else
                {
                    upper = middle;
                }
            } 
    
            return lower;
            //throw std::logic_error("Waiting to be implemented");
        }
    };
    
    #ifndef RunTests
    int main()
    {
        std::vector<int> v { 1, 3, 5, 7 };
        std::cout << SortedSearch::countNumbers(v, 4);
    }
    #endif
    

    你会得到 4/4。

    【讨论】:

      【解决方案4】:

      使用向量已排序这一事实可以通过不查看整个向量来帮助加快代码速度。

      If (sortedVector[i]>=lessthan)
      {
           return a;
      }
      

      当您遇到大于小于的元素时,这将终止您的循环,并为您节省不必要的迭代。对于您给定的 main,它只会经历 2 次迭代而不是 4 次。

      虽然这并没有专门解决上述问题,但看看它是否可以通过测试用例为您提供足够的性能提升以通过它们。这也将使每次运行的最坏情况性能 O(n) 而不是 O(n)

      【讨论】:

      • 谢谢,但是这里的问题要求计算小于参数lessThan的向量元素的数量。所以,我认为它应该经过 4 次迭代并检查每个成员的值。
      • 问题说向量已排序(我假设它是按升序排列的)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-09
      • 1970-01-01
      • 1970-01-01
      • 2011-06-28
      • 2010-09-27
      • 2019-04-10
      相关资源
      最近更新 更多