将整数分配给std :: vector中的已排序的唯一元素

时间:2014-03-11 21:21:53

标签: c++ sorting vector stl

实施例: 给定std::vector<string> v = {"C", "A", "B", "A"}

我们寻求

vector<size_t> s:= {2,0,1,0}

这些整数是根据v中唯一值的排序顺序分配的:0-"A", 1-"B", 2-"C"

可能的方法是:

vector<string> unique(v.begin(), v.end());
unique.sort();
unique.erase(std::unique(unique.begin(), unique.end()), unique.end());
vector<size_t> s(v.size());
for(size_t i(0); i < v.size(); i++)
{
   s[i] = std::lower_bound(unique.begin(), unique.end(), v[i]) - unique.begin();
}

是否有更优雅,更紧凑,最重要的是,高效方法来执行相同的例程?我知道如何使用std::mapunordered_map执行此操作,但不按排序顺序执行此操作。

更新 显然渐近复杂性无法改善 - 下限为O(n*logn)(如上所述)。但是,不同的O(n*logn)算法可能会超越常数或者更好:)

3 个答案:

答案 0 :(得分:2)

关闭袖口代码:

set<string> unique( v.begin(), v.end() );
vector<int> s( v.size() );
for( int i = 0; i < (int) v.size(); ++i )
{
   s[i] = unique.find( v[i] ) - unique.begin();
}

我认为这更优雅,我怀疑它可能会更有效率。

免责声明:编译人员未触及代码,未执行检查逻辑......


更新:检查代码,嘿set迭代器不支持减法。所以效率可能不太好。但我觉得它看起来更好(更优雅)! : - )

测试代码:

#include <iostream>
#include <set>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;

auto main()
    -> int
{
    vector<string> const v = {"C", "A", "B", "A"};
    set<string> const unique( v.begin(), v.end() );

    vector<int> s( v.size() );
    for( int i = 0; i < (int) v.size(); ++i )
    {
       s[i] = distance( unique.begin(), unique.find( v[i] ) );
    }

    copy( s.begin(), s.end(), ostream_iterator<int>( cout, " " ) );
    cout << endl;
}

答案 1 :(得分:1)

对两个实现的一点分析:使用有序向量(初始)和一组。 带有排序向量的初始变量应该比使用集合更快。

在大O方面,这些决定是平等的。在初始化阶段,我们只需要对向量进行排序并构建集合。 std :: sort的复杂性是O(n logn) worst case,因为C ++ 11,插入std::set是相同的O(n logn)(标准2011 23.2.4)。 (作为规则集实现为红黑树。) 在搜索的第二步,lower_bound是O(logn),同样是set::find

但是在常量的条款中,在有序向量(lower_bound)中搜索应该比set::find更快,因为它使用连续内存,这对于处理器缓存很有用。例如,this analysis显示速度提高了两倍,并且使用的内存减少了3倍。 人们可以测量具体的数据和硬件(实际上结果非常有趣)。

因此,如果我们不需要在有序向量中插入,则使用它是更可取的。

答案 2 :(得分:0)

如果您想提高效率,并且只有少量不同的值可以轻松映射到小整数(如字母),请查看http://en.wikipedia.org/wiki/Counting_sort

有很多实施例子。请参阅:http://www.codeproject.com/Tips/290197/Cplusplus-Count-Sort-Implementation 一个。