如何进一步优化这个简单的算法?

Rak*_*111 11 c++ algorithm optimization performance c++11

注意:这是编程挑战


这个挑战需要使用std::set.

输入

  • 一个号码 n
  • n每个j和每条线k

样本输入:

5
1 4
2 1
1 6
3 4
1 2
Run Code Online (Sandbox Code Playgroud)

j用于操作:1插入k,2删除k(如果有k),3查找k

对于j == 3,输出YesNoif k是在std::set.


我做了不同版本的算法,但都太慢了.我尝试了不同的std功能,但std::find似乎是最快的功能,但仍然太慢了.实现我自己会更糟,所以也许我错过了图书馆的功能.我真的不知道如何进一步优化它.目前我有这个:

int main()
{
    std::set<int> set{};
    int Q = 0;
    std::cin >> Q;

    int type = 0;
    int x = 0;
    for (int i = 0; i < Q; ++i)
    {
        std::cin >> type;
        std::cin >> x;

        if (type == 1)
            set.insert(x);
        else if (type == 2)
            set.erase(x);
        else if (type == 3)
            std::cout << (std::find(std::begin(set), std::end(set), x) != std::end(set) ? "Yes" : "No") << '\n';
            //Condition may be std::find, std::count or std::binary_search
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)


挑战要求它在2秒内运行.以下是我的结果:

Function              Time           % over
std::find          -> 7.410s         370.50%
std::count         -> 7.881s         394.05%
std::binary_search -> 14.050s        702.50%
Run Code Online (Sandbox Code Playgroud)

如您所见,我的算法比所需算法慢3倍.瓶颈显然是那些功能:

Function               % of total time 
std::find          ->  77.61%
std::count         ->  80.80%
std::binary_search ->  87.59%
Run Code Online (Sandbox Code Playgroud)

但目前我没有比使用std::find或类似功能更好的想法.有人有办法/想法进一步优化我的代码吗?还是有一些我不知道的明显瓶颈?

Vau*_*ato 18

你想要使用set.find()而不是std::find(set.begin(),set.end()).

set.find()将使用set的内部结构在O(log(n))时间内定位密钥.然而std::find,线性搜索,无论使用何种容器类型,都需要O(n)时间.