合并无额外内存的向量
我遇到了两个向量合并的代码段,其中一个向量的元素在重复情况下受到青睐:
std::vector<String> fields1 = fieldSource1.get();
std::vector<String> fields2 = fieldSource2.get();
// original
fields1.insert(std::end(fields1), std::begin(fields2), std::end(fields2));
std::stable_sort(std::begin(fields1), std::end(fields1));
fields1.erase(std::unique(std::begin(fields1), std::end(fields1)), std::end(fields1));
return fields1;
鉴于字符串在它们各自的向量中是唯一的,并且输出向量中字符串的顺序是无关紧要的,我认为我可以使这个算法更高效。
我想避免额外的内存分配std :: set_union()和std :: set_diff()。
(由于在调整大小期间迭代器失效,直接将std :: set_diff插入到原始矢量不是一个选项)
我结束了这一点,这是std :: set_diff与一个迭代器替换为索引:
std::sort(std::begin(fields1), std::end(fields1));
std::sort(std::begin(fields2), std::end(fields2));
// Initialize iterators by index in case of resizing
size_t index = 0;
size_t end = std::size(fields1);
std::remove_copy_if(std::begin(fields2), std::end(fields2), std::back_inserter(fields1),
[&fields1, &index, end](String field)->bool{
auto begin = std::begin(fields1);
found = std::lower_bound(begin+index, begin+end, field);
index = std::distance(begin, found);
return (*found) == field;
});
return fields1;
我的问题是:我可以让这个合并操作更有效率吗? 如果没有,我可以让它更具可读性吗?
如果要将它们保持在已排序或可合并的状态,将一串字符串表示为向量是无效的。 最好使用另一个容器,比如std :: set或std :: unordered_set,它具有更好的性能保证。
请注意,任何尝试对字符串进行排序的解决方案都可能会进一步片段化内存,并且比首先创建正确的数据结构的内存压力增加更多。
如果您必须将它们保留为字符串向量,那么您可以考虑创建一个散列表,其中包含在每个点上看到的所有字符串,然后只允许插入其哈希尚未显示的字符串。 如果您有大量重复项,则此方法可能比独立排列每个列表更有效。
typedef std::size_t hash_type;
typedef std::string value_type;
typedef std::vector< value_type > values_type;
typedef std::hash< value_type > value_hash_type;
typedef std::unordered_set< hash_type > hash_set_type;
bool is_new_hash(hash_set_type &hash_set,
const hash_type one_hash
)
{
if (hash_set.find(one_hash) == hash_set.end())
{
hash_set.insert(one_hash);
return true;
}
return false;
}
int main()
{
values_type str1, str2, dest;
str1.push_back("c");
str1.push_back("a");
str1.push_back("b");
str2.push_back("c");
str2.push_back("d");
hash_set_type hash_set;
value_hash_type value_hash;
for (auto &s : str1)
{
if (is_new_hash( hash_set, value_hash( s ) ))
dest.push_back(s);
}
for (auto &s : str2)
{
if (is_new_hash(hash_set, value_hash(s)))
dest.push_back(s);
}
std::sort(dest.begin(), dest.end());
}
链接地址: http://www.djcxy.com/p/79199.html
上一篇: Merging vectors without extra memory
下一篇: Change size of vector without destroying reserved elements