Queue with unique entries in c++

I need to implement a queue containing unique entries(no duplicates) in C or C++. I am thinking of maintaining a reference of elements already available in queue but that seems very inefficient.

Kindly let me know your suggestions to tackle this.

C# List with Unique Entries

I have a list like this, List A ItemNum FileName 001 A.txt,B.txt,A.txt,B.txt 002 A.txt,C.txt,A.txt,C.txt I need to make a list like this. ItemNum FileName 001 A.txt,B.txt 002 A.txt,C.txt Is there an

Select unique entries of column and filter these by unique entries of another one

I have the following hypothetic table: col_1 | col_2 a 1 b 1 c 1 d 2 e 2 a 3 b 3 c 3 What I want is the number of unique entries in column 1 (5 – a, b, c, d, e) filtered by the unique entries of colu

Removal of unique entries

I am working with a hospital dataset in ACCESS 2010 that has records identified by patient number. I have 350,000 entries from around 200,000 unique patients. I want to REMOVE all those patients who a

remove unique_ptr from queue

I’m trying to figure out how/if I can use unique_ptr in a queue. // create queue std::queue<std::unique_ptr<int>> q; // add element std::unique_ptr<int> p (new int{123}); q.push(std:

Azure Queue unique message

I would like to make sure that I don’t insert a message to the queue multiple times. Is there any ID/Name I can use to enforce uniqueness?

Remove duplicate entries from a redis queue in resque

I am using resque and i have a redis queue.It has certain duplicate entries . I need to remove the duplicate entires .How do i remove those duplicate entries? I am enqueing the id of a certain object

mysql query to find unique entries with multiple cloumns

When I have multiple columsn, like a, b and c. When I simply using SELECT DISTINCT c FROM ‘tablename’, it only shows colum C. I want to select entries that are unique and show all three rows. Not uni

Excel Name-Manager – Show only Unique Entries

I use the Excel named range in a VBA user form as a datasource for a dropdown list field. This works fine, but is it possible to show only the unique entries? The data to be filtered is in C5:C1000 of

Pandas – Identify % of unique entries per column

Say I have a dataframe. I would like to find out, for each column, how many unique entries I have with respect to the total size of the dataframe (a percentage). In other words, I want to get a sense

Getting the latest 5 unique entries

I have an Access database that I am interacting with using JET with the following structure: ID UsersID 1 1 2 2 3 2 4 3 5 1 What I am trying to do is get the latest unique entries. eg: ID UsersID 5 1

Answers

queuing:

  • use std::set to maintain your set of unique elements
  • add any element that you were able to add to the std::set to the std::queue

dequeueing:

  • remove element from std::queue and std::set

How about an auxiliary data structure to track uniqueness:

std::queue<Foo> q;
std::set<std::reference_wrapper<Foo>> s;

// to add:

void add(Foo const & x)
{
    if (s.find(x) == s.end())
    {
        q.push_back(x);
        s.insert(std::ref(q.back()));  // or "s.emplace(q.back());"
    }
}

Or, alternatively, reverse the roles of the queue and the set:

std::set<Foo> s;
std::queue<std::reference_wrapper<Foo>> q;

void add(Foo const & x)
{
    auto p = s.insert(x);       // std::pair<std::set<Foo>::iterator, bool>
    if (s.second)
    {
        q.push_back(std::ref(*s.first));  // or "q.emplace_back(*s.first);"
    }
}

std::queue is a container adaptor and uses relatively few members of the underlying Container. You can easily implement a custom container that contains both: an unordered_map of reference_wrapper<T> and a deque<T>. It needs at least members front and push_back. Check inside that hash_map when push_back of your container is called and reject accordingly (possibly throw). To give the complete example:

#include <iostream>
#include <set>
#include <deque>
#include <queue>
#include <unordered_set>
#include <functional>

namespace std {

// partial specialization for reference_wrapper
// is this really necessary?
template<typename T>
class hash<std::reference_wrapper<T>> {
public:
  std::size_t operator()(std::reference_wrapper<T> x) const 
  { return std::hash<T>()(x.get()); }
};

}

template <typename T>
class my_container {
  // important: this really needs to be a deque and only front
  // insertion/deletion is allowed to not get dangling references
  typedef std::deque<T> storage;
  typedef std::reference_wrapper<const T> c_ref_w;
  typedef std::reference_wrapper<T> ref_w;
public:  
  typedef typename storage::value_type value_type;
  typedef typename storage::reference reference; 
  typedef typename storage::const_reference const_reference; 
  typedef typename storage::size_type size_type;

  // no move semantics
  void push_back(const T& t) {
    auto it = lookup_.find(std::cref(t));
    if(it != end(lookup_)) {
      // is already inserted report error
      return;
    }
    store_.push_back(t);
    // this is important to not have dangling references
    lookup_.insert(store_.back());
  }

  // trivial functions

  bool empty() const { return store_.empty(); }
  const T& front() const { return store_.front(); }
  T& front() { return store_.front(); }

  void pop_front() { lookup_.erase(store_.front()); store_.pop_front();  }
private:
  // look-up mechanism
  std::unordered_set<c_ref_w> lookup_;
  // underlying storage
  storage store_;
};

int main()
{
  // reference wrapper for int ends up being silly 
  // but good for larger objects
  std::queue<int, my_container<int>> q;
  q.push(2);
  q.push(3);
  q.push(2);
  q.push(4);
  while(!q.empty()) {
    std::cout << q.front() << std::endl;
    q.pop();
  }

  return 0;
}

EDIT: You will want to make my_container a proper model of container (maybe also allocators), but this is another full question. Thanks to Christian Rau for pointing out bugs.

There is one very important point you’ve not mentioned in your question, and that is whether your queue of items is sorted or have some kind of ordering (called a Priority queue), or unsorted (called a plain FIFO). The solution you choose will depend only on the answer to this question.

  1. If your queue is unsorted, then maintaining an extra data structure in addition to your queue will be more efficient. Using a second structure which is ordered in some way to maintain the contents of your queue will allow you check if an item already exists in your queue or not much quicker that scanning the queue itself. Adding to the end of an unsorted queue takes constant time and can be done very efficiently.

  2. If your queue must be sorted, then placing the item into the queue requires you to know the item’s position in the queue, which requires the queue to be scanned anyway. Once you know an item’s position, you know if the item is a duplicate because if it’s a duplicate then an item will already exist at that position in the queue. In this case, all work can be performed optimally on the queue itself and maintaining any secondary data structure is unnecessary.

The choice of data structures is up to you. However, for (1) the secondary data structure should not be any kind of list or array, otherwise it will be no more efficient to scan your secondary index as to scan the original queue itself.