2015-08-26 27 views
2

我正在使用Armadillo在C++中进行线性代数计算。如何计算C++中向量的重复条目

例如,有一个

vector a = (1,1,2,2,0,2,1,0) 

我想返回一个矩阵

(0, 2) //means 0 shows 2 times in the vector 
(1, 3) //1 shows 3 times 
(2, 3) //2 shows 3 times 

有什么功能可以实现这样的工作吗?

+4

@JohnBupit,但更好地使用'地图' – Lol4t0

+0

@ Lol4t0的确。我没有通过阅读这个问题。 –

+0

使用[unique()](http://arma.sourceforge.net/docs.html#unique)和[hist()](http://arma.sourceforge.net/docs)的组合很容易实现。 HTML#HIST)。请参阅下面我的详细答案。 – mtall

回答

7

正如评论中所述,您可以使用std::map来收集结果。然后,您可以根据需要转换为矩阵。你可以跳过地图步骤,如果它已经用你之前的行预先初始化,可以直接使用矩阵。

至于执行此操作的函数,您可以使用<algorithm>中的std::for_each以及lambda表达式,尽管当循环很好时它看起来过度。

#include <algorithm> 
#include <iostream> 
#include <vector> 
#include <map> 

using namespace std; 

int main() 
{ 
    vector<int> v{1,1,2,2,0,2,1,0}; 
    map<int,int> dup; 

    for_each(v.begin(), v.end(), [&dup](int val){ dup[val]++; }); 

    for(auto p : dup) { 
     cout << p.first << ' ' << p.second << endl; 
    } 

    return 0; 
} 
+0

所以,我们可以看到'for_each'完成这个工作,而*范围*显示:-)。 – Jarod42

+2

'for_each'的替代方法是'for(auto x:v)++ dup [x];' –

+0

@ Jarod42 yep,bases covered =) – paddy

2

这里的另一个解决方案中,仅使用Armadillo的函数,以及C++ 11编译器:

vec a = {1,1,2,2,0,2,1,0}; // vec holds elements of type 'double' 

vec b = unique(a); 

uvec c = hist(a,b); // uvec holds unsigned integers 

mat X(b.n_rows, 2); 

X.col(0) = b; 
X.col(1) = conv_to<vec>::from(c); 

X.print("X:"); 

说明:

  • VEC B = unique(a)创建包含独特的元件的载体a,按升序排序
  • uvec C = hist(a,b)创建在一个元件的计数的直方图,使用b作为仓中心
  • conv_to<vec>::from(c)转换Ç(矢量与无符号整数)以相同的向量类型一个