2016-07-23 47 views
0

我正在翻译从C#到C++的一些代码,我被困在一个看似基本的问题上。C++ Equiv。 C#的intQueue.Contains()

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

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

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

+1

'intQueue'是一个不是类型的变量。可能类型是'队列'?我将在C++中使用'deque'和'find'成员函数。 –

+0

没错。作为一个例子,intQueue是一个变量名。也许一个德克更适合这种情况。感谢您的评论。我会研究一下。 – trademark

+1

更正。我的意思是'std :: find'。 deque没有找到成员函数。 –

回答

2

我可能会使用位于<algorithm>std::find()。您需要将它传递给开始和结束迭代器,这些迭代器无法使用queue类进行访问,所以一个好的替代方案是deque

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 
0

“PC勒德分子”有答案,但在这里它是在你的榜样的直接转换:

#include <deque> 
#include <algorithm> 

... 

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

你不能用'queue'来做这件事。 'queue'不允许你访问开始和结束迭代器。 –

+0

@PCLuddite:你说得对 - 谢谢你。 –

0

因此,如果使用的是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; 
} 
0

如果你可以使用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实例在弹出头之后放置元素,或者就地对数据结构进行排序并使用std::binary_search来检查期望的元素有:

#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顺序的状态作为状态,而第二种方法不适用。