added function to remove duplicates, preserve order of dbit

This commit is contained in:
Erik Fröjdh
2025-12-03 12:14:35 +01:00
parent 134137ead0
commit 1c31a85a43
3 changed files with 62 additions and 7 deletions

View File

@@ -2568,17 +2568,15 @@ std::vector<int> Module::getReceiverDbitList() const {
void Module::setReceiverDbitList(std::vector<int> list) {
LOG(logDEBUG1) << "Setting Receiver Dbit List";
if (list.size() > 64) {
throw RuntimeError("Dbit list size cannot be greater than 64\n");
}
for (auto &it : list) {
if (it < 0 || it > 63) {
throw RuntimeError("Dbit list value must be between 0 and 63\n");
}
}
std::sort(begin(list), end(list));
auto last = std::unique(begin(list), end(list));
list.erase(last, list.end());
auto r = stableRemoveDuplicates(list);
if(r)
LOG(logWARNING) << "Removed duplicated from receiver dbit list";
StaticVector<int, MAX_RX_DBIT> arg = list;
sendToReceiver(F_SET_RECEIVER_DBIT_LIST, arg, nullptr);

View File

@@ -6,6 +6,7 @@
#include <algorithm>
#include <memory>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <type_traits>
@@ -155,6 +156,10 @@ template <typename Container> bool hasDuplicates(Container c) {
return pos != c.end(); // if we found something there are duplicates
}
/**
* @brief Sorts the container and removes duplicated elements
* returns true if elements were removed otherwiese false
*/
template <typename T>
typename std::enable_if<is_container<T>::value, bool>::type
removeDuplicates(T &c) {
@@ -167,6 +172,29 @@ removeDuplicates(T &c) {
return false;
}
/**
* @brief Removed duplicated entries while preserving the oder
* returns true if elements were removed otherwiese false
*/
template <typename T>
typename std::enable_if<is_container<T>::value, bool>::type
stableRemoveDuplicates(T &c) {
auto containerSize = c.size();
std::set<typename T::value_type> seen;
c.erase(
std::remove_if(c.begin(), c.end(),
[&](const typename T::value_type& val) {
return !seen.insert(val).second; // erase if already seen
}),
c.end()
);
if (c.size() != containerSize) {
return true;
}
return false;
}
} // namespace sls
#endif // CONTAINER_UTILS_H

View File

@@ -153,13 +153,35 @@ TEST_CASE("check for duplicates in vector of pairs") {
REQUIRE(hasDuplicates(vec) == true);
}
TEST_CASE("remove duplicates from vector") {
TEST_CASE("sorts the vector and remove duplicates") {
std::vector<int> v{5, 6, 5, 3};
auto r = removeDuplicates(v);
CHECK(r == true); // did indeed remove elements
CHECK(v == std::vector<int>{3, 5, 6});
}
TEST_CASE("remove duplicates but keep order") {
std::vector<int> v{5, 6, 5, 3};
auto r = stableRemoveDuplicates(v);
CHECK(r == true); // did indeed remove elements
CHECK(v == std::vector<int>{5, 6, 3});
}
TEST_CASE("remove duplicates but keep order, all elements the same ") {
std::vector<char> v{'c', 'c', 'c', 'c', 'c', 'c'};
auto r = stableRemoveDuplicates(v);
CHECK(r == true); // did indeed remove elements
CHECK(v == std::vector<char>{'c'});
}
TEST_CASE("remove duplicates but keep order, pattern ") {
std::vector<int> v{8,1,2,8,8,3,2};
auto r = stableRemoveDuplicates(v);
CHECK(r == true); // did indeed remove elements
CHECK(v == std::vector<int>{8,1,2,3});
}
TEST_CASE("remove duplicated empty vector") {
std::vector<int> v;
auto r = removeDuplicates(v);
@@ -167,4 +189,11 @@ TEST_CASE("remove duplicated empty vector") {
CHECK(v == std::vector<int>{});
}
TEST_CASE("remove duplicated empty vector using stable version") {
std::vector<int> v;
auto r = stableRemoveDuplicates(v);
CHECK(r == false); // no elements to remove
CHECK(v == std::vector<int>{});
}
} // namespace sls