I'm trying to make a generic function which will copy elements without duplicates from one block to another. Function accepts three pointers/iterators and must work for all types of iterators. Function should return a pointer/iterator that points exactly one place behind the destination block.
p1 and p2 are from the same type. However, p3 doesn't have to be the same type as p1 and p2.
#include <iostream>
#include <algorithm>
#include <vector>
template<typename iter_type1, typename iter_type2>
auto CopyWithoutDuplicate(iter_type1 p1, iter_type1 p2, iter_type2 p3){
int n=std::distance(p1,p2);
std::unique_copy(p1,p2,p3);
p3 =n;
return p3;
}
int main()
{
std::string s="abc defabcd ghidef",str;
std::vector<int>a{1,1,2,2,3,4,3,5},b;
auto it1=CopyWithoutDuplicate(s.begin(),s.end(),str.begin());
while(it1!=str.begin())
{
std::cout<<*it1;
it1--;
}
std::cout<<endl;
auto it2=CopyWithoutDuplicate(a.begin(),a.end(),b.begin());
while(it2!=b.begin())
{
std::cout<<*it2<<" ";
it2--;
}
return 0;
}
Correct output would be:
abc defghi
1 2 3 4 5
I tried to use std::unique_copy
for this, but I don't know where I made mistaked in my code. This doesn't print anything on screen.
CodePudding user response:
CopyWithoutDuplicate
can be simplified.
auto CopyWithoutDuplicate(iter_type1 p1, iter_type1 p2, iter_type2 p3){
return std::unique_copy(p1,p2,p3);
}
The working example:
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <unordered_set>
template<typename iter_type1, typename iter_type2>
iter_type2 CopyWithoutDuplicate(iter_type1 p1, iter_type1 p2, iter_type2 p3){
std::unordered_set<typename std::iterator_traits<iter_type1>::value_type> m;
for (; p1 != p2; p1) {
if (m.count(*p1) != 0)
continue;
*p3 = *p1;
m.insert(*p1);
}
return p3;
}
int main()
{
std::string s="abc defabcd ghidef",str;
std::vector<int>a{1,1,2,2,3,4,3,5},b;
CopyWithoutDuplicate(s.begin(),s.end(),std::back_insert_iterator(str));
for(char c : str)
std::cout<<c;
std::cout<<std::endl;
CopyWithoutDuplicate(a.begin(),a.end(),std::back_insert_iterator(b));
for(int n : b)
std::cout<<n<<" ";
return 0;
}
Output
abc defghi
1 2 3 4 5