The question is
Implement the function unique_in_order which takes as argument a sequence and returns a list of items without any elements with the same value next to each other and preserving the original order of elements.
For example:
uniqueInOrder("AAAABBBCCDAABBB") == {'A', 'B', 'C', 'D', 'A', 'B'}
uniqueInOrder("ABBCcAD") == {'A', 'B', 'C', 'c', 'A', 'D'}
uniqueInOrder([1,2,2,3,3]) == {1,2,3}
Now my solution is
template <typename T>
std::vector<T> uniqueInOrder(const std::vector<T>& iterable){
std::vector<T> unique_set;
T last = 0;
for(auto & element : iterable) {
if(element != last) {
unique_set.push_back(element);
}
last = element;
}
return unique_set;
}
std::vector<char> uniqueInOrder(const std::string& iterable){
std::vector<char> unique_set;
char last = 0;
for(auto & element : iterable) {
if(element != last) {
unique_set.push_back(element);
}
last = element;
}
return unique_set;
}
The problem is that sometimes the first element is 0. What can I assign last that will never match an input? I tried using NULL but I think that just compiled to 0 anyway.
There's an algorithm to do just that called std::unique_copy
template <typename T>
std::vector<T> uniqueInOrder(const std::vector<T>& iterable){
std::vector<T> unique_set;
std::unique_copy(iterable.begin(), iterable.end(), std::back_inserter(unique_set));
return unique_set;
}
// same thing for std::string
std::vector<char> uniqueInOrder(const std::string& iterable){
std::vector<char> unique_set;
std::unique_copy(iterable.begin(), iterable.end(), std::back_inserter(unique_set));
return unique_set;
}
Depending on the type of T
, there could be no impossible value. For ints and chars, every single value is possible. The best option is to use something like std::optional
, which provides an explicit valueless value.
// this will be valueless and not equal to any value
std::optional<T> last{};
// assign it with
last = element;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With