samedi 29 juillet 2017

Delete Duplicate Members of N-Dimensional Vector

Recursive templates are still quite confusing to me, and I don't feel like I'm using them as well as I should be. For example, I tried to use recursive templates to write a function that will remove all duplicate members of an n-dimensional vector, and I believe that I have some code that works. However, I'm almost confident that there's a better way to do this:

  template <typename T>
  void remove_if_duplicate(std::vector<T>& vec, bool at_end)
  {
    static std::set<T> seen;
    if(!at_end)
    {
      auto newEnd = std::remove_if(vec.begin(), vec.end(), [=](const T& value)
      {
        if(seen.find(value) != std::end(seen))
          return true;

        seen.insert(value);
        return false;
      });
      vec.erase(newEnd, vec.end());
      std::cout << "\n\nhere: " << at_end << "\n\n";
    }
    if(at_end) {seen.clear();}
  }

  template <typename T>
  void remove_if_duplicate(std::vector<std::vector<T>>& v, bool at_end)
  {
    if(!at_end)
    {
      for(unsigned int i = 0; i < v.size(); i++)
      {
        remove_if_duplicate(v[i], at_end);
      }
    }
    if(at_end) {remove_if_duplicate(v[0], at_end);}
  }

template <typename T>
void remove_duplicates(std::vector<std::vector<T>>& v)
{
  remove_if_duplicate(v, false);
  remove_if_duplicate(v, true);
}

See an example here: http://ift.tt/2v80T10

Notice how I declare the set variable "seen" as a static variable of the base function. I have do this so that I still have access to previous items that I have "seen" before even when iterating through multidimensional vectors. I cannot declare the "seen" variable inside the second function because the base type that the multidimensional vectors is templated on is unknown at that point (and then the case of a single-dimensional vector wouldn't work either). So then I have to pass booleans into these functions in order to decide when to actually clear the static set variable so that I can use this function again for other n-dimensional vectors.

While it seems to work so far and is giving me the behavior I want, I'm not sure if any unexpected bugs will appear as a result of my poor implementation. I think that the way that I have done this here is far from ideal, and I'm sure there's a better, more efficient way. How would you do it differently?

Aucun commentaire:

Enregistrer un commentaire