【问题标题】:C++ Equiv. of C#'s intQueue.Contains()C++ 等价物。 C# 的 intQueue.Contains()
【发布时间】:2016-11-27 00:34:47
【问题描述】:

我正在将大量代码从 C# 转换为 C++,但我遇到了一个看似基本的问题。

我想做一个简单的评估,看看 int 的 FIFO 队列是否包含特定的 int。这并不难做到,但我似乎无法在 Google 上找到一个好的示例。

if(intQueue.Contains(value)){ /* do some stuff */ }

我在here 上发现了同样的问题,但答案并不真正适用于我的情况。请帮忙!谢谢!

【问题讨论】:

  • intQueue 是变量而不是类型。大概类型是Queue<int>?我会在 C++ 中使用 dequefind 成员函数。
  • 对。 intQueue 是此处用作示例的变量名称。也许双端队列更适合这种情况。感谢您的评论。我会调查的。
  • 更正。我的意思是std::find。 deque 没有 find 成员函数。
  • list<> 够吗?
  • STL 队列是底层容器的适配器——通常是双端队列或列表。两者都直接支持将它们用作队列。一个奖励——你可以在它们上使用 std::find。

标签: c# c++ queue translate fifo


【解决方案1】:

我可能会使用位于<algorithm>std::find()。您需要将开始和结束迭代器传递给它,使用 queue 类无法访问它,因此deque 是一个不错的选择。

双端队列的功能与队列类似,可以推送和弹出项目,但项目不限于“先进先出”模型。物品可以从后面和前面弹出和推送。这就是 queue 类默认在内部存储其元素的方式。

#include <deque>
#include <algorithm>
#include <iostream>

int main()
{
    // initialize deque with ints 3, 2, 1
    std::deque<int> intDeque{ 3, 2, 1 };

    auto it = std::find(intDeque.begin(), intDeque.end(), 2); // find 2 in intDeque

    if (it == intDeque.end()) {
        std::cout << "Not found" << std::endl;
    }
    else {
        std::cout << "Found!" << std::endl;
    }

    return 0;
}

上面使用的是c++11,如果你没有访问权限,你可以这样做:

std::deque<int> intDeque;
// push elements onto the deque
intDeque.push_back(3);
intDeque.push_back(2);
intDeque.push_back(1);

std::deque<int>::iterator it = std::find(intDeque.begin(), intDeque.end(), 2); // find 2 in intDeque

【讨论】:

    【解决方案2】:

    如果你可以使用 C++ 11 及更高版本,我建议使用any_of 算法:

    #include <algorithm>
    
    if(std::any_of(intQueue.begin(), intQueue.end(), value))
    {
      //do some stuff here
    }
    

    使用什么数据结构并不重要,只要它提供迭代器即可。

    注意!您唯一需要注意的是所需的复杂性。在这里,您可能会得到 O(N) 比较。 然而,如果底层的队列已知是排序的(例如优先队列),你可以改进运行时间为O(log N)。唯一的问题是(例如std::priority_queue)不为您提供迭代器,并且您将需要另一个std::priority_queue 实例在您弹出头部后将元素放入,或者您对数据结构进行就地排序并使用@987654323 @ 检查所需的元素是否存在:

    #include <deque>
    #include <algorithm>
    
    // std::deque<int> intQueue;
    std::sort(intQueue.begin(), intQueue.end()); // !!! this is O(N log N) !!!
    
    
    if(std::binary_search(intQueue.begin(), intQueue.end(), value)) // O(log N)
    {
      //do some stuff here
    }
    

    事实证明:你需要在初始排序后保持排序条件(插入时间O(log N)),否则你会得到更糟糕的结果运行时复杂度。特别是,您可能需要将元素作为 FIFO 顺序的状态,而不是第二种方法不适用。

    【讨论】:

      【解决方案3】:

      “PC Luddite”有答案,但这里是您的示例的直接转换:

      #include <deque>
      #include <algorithm>
      
      ...
      
      std::deque<int> intQueue;
      if (std::find(intQueue.begin(), intQueue.end(), value) != intQueue.end())
      {
      }
      

      【讨论】:

      • 您不能使用queue 执行此操作。 queue 不允许您访问开始和结束迭代器。
      【解决方案4】:

      因此,如果不接受直接使用 dequelist 并且 queue 不适合有效搜索。让我们用 cbegin/cend 扩展队列并启用std::find

      template <typename _Ty, typename _Container = deque<_Ty>>
      class searchable_queue : public std::queue<_Ty, _Container>
      {
      public:
          template<class... _Axx>
          searchable_queue(_Axx&&... _Ax) 
              : std::queue<_Ty, _Container>(std::forward<_Axx>(_Ax)...)
          {}
      
          typename _Container::const_iterator cbegin() const noexcept
          { 
               return (c.cbegin());
          }
      
          typename _Container::const_iterator cend() const noexcept
          {   
              return (c.cend());
          }
      };
      
      int main() 
      {
          list<int> l = { 11, 22, 44, 55 };
          auto q = searchable_queue<int,list<int>>(std::move(l));
          auto res = std::find(q.cbegin(), q.cend(), 22);
          cout << boolalpha << (res != q.cend()) << '\n'; //displays 'true'
          res = std::find(q.cbegin(), q.cend(), 77);
          cout << boolalpha << (res != q.cend()) << '\n'; // displays 'false'
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 2010-10-05
        • 1970-01-01
        • 2022-12-08
        • 1970-01-01
        • 1970-01-01
        • 2013-08-19
        • 2010-11-19
        • 1970-01-01
        • 2011-04-02
        相关资源
        最近更新 更多