2011-05-23 6 views
5

Voy a explicar lo que hace el 'que' la función:¿Existe una función equivalente en C/C++ a GNU-R que()?

desde GNU-R ayuda:

las que los índices son VERDADERO?

Proporcione los índices "VERDADEROS" de un objeto lógico, lo que permite índices de matriz.

o mostrando algo de código: (GNU-R comienza con índices de conteo 1)

> x <- c(1,2,3,1,3,5); 
> which(x == 1); 
[1] 1 4 
> which(x == 3); 
[1] 3 5 
> ll <- c(TRUE,FALSE,TRUE,NA,FALSE,FALSE,TRUE); 
> which(ll); 
[1] 1 3 7 

¿Alguien sabe una función similar en C/C++?

Gracias por su ayuda

rinni

+0

['std :: find_if'] (http://en.cppreference.com/w/cpp/algorithm/find) o [' std :: copy_if'] (http://en.cppreference.com/ w/cpp/algorithm/copy) según lo que quieras hacer con él. (O cualquiera de varias otras llamadas a la biblioteca) –

Respuesta

6

Usted tiene que entender que se R vectorizado, mientras que C, ante todo, trabaja en piezas individuales de datos atomizados: una sola int, double, ...

Con C++, se puede mirar en los algoritmos de STL con el que se acercarse a esto

Por último, en la intersección R y C++, nuestro paquete Rcpp tiene algunas operaciones vectorizadas en C++ que imitan algunas operaciones; ver la viñeta en pdf de Rcpp-sugar para obtener más información (y/o algunas de nuestras charlas sobre Rcpp).

+0

tiene toda la razón. Mi primer acercamiento estaba bastante centrado en R. Supongo que tengo que probarlo para el punto de vista C++. – rinni

2

el algoritmo std::find_if debe hacer el truco - en conjunto con un bucle debo añadir.

3

Crea un objeto de functor que puedes inicializar con el valor de coincidencia, e iterador sobre tu lista usando std::for_each. Así, por ejemplo:

vector<int> values; 
//fill your vector with values; 

struct match_functor 
{ 
    vector<int> value_array; 
    int match_value; 

    match_functor(int value): match_value(value) {} 

    void operator() (int input_value) 
    { 
     if(match_value == input_value) 
      value_array.push_back(input_value); 
    } 
}; 

match_functor matches(1); 
std::for_each(values.begin(), values.end(), matches); 

Ahora su matriz de valores resultado se puede acceder mediante matches.value_array[INDEX].

Como alternativa, si simplemente desea tener los índices del del vector original, en lugar de los valores reales, entonces se puede hacer algo como esto para su objeto funtor:

struct match_functor 
{ 
    vector<int> index_array; 
    int match_value; 
    int index; 

    match_functor(int value): match_value(value), index(0) {} 

    void operator() (int input_value) 
    { 
     if(match_value == input_value) 
      index_array.push_back(index); 

     index++; 
    } 
}; 

match_functor matches(1); 
matches = std::for_each(values.begin(), values.end(), matches); 

ahora matches.index_array[INDEX] llevará a cabo las indicaciones del vector orignal que coinciden con el valor 1, y no los valores reales del vector original.

+1

su primer fragmento de código es simplemente un sustituto más complicado de 'std :: remove_copy_if'. –

+0

No está eliminando ningún valor ... hace una copia del valor deseado N veces para el número de ocurrencias en el vector original. – Jason

+2

@Jason Sí, copia los valores del vector de entrada en algunos otros, eliminando (no copiando) cualquier valor que no se ajuste a algún predicado. Eso es lo que hace 'std :: remove_copy_if'. –

Cuestiones relacionadas