Estructura de datos de array paralela en C++

Jinku Hu 12 octubre 2023
Estructura de datos de array paralela en C++

Este artículo demostrará cómo implementar una estructura de datos de array paralela en C++.

Utilice el contenedor std::vector para implementar una clase de array paralela personalizada en C++

un array paralela es la estructura de datos abstracta que implementa un array de varios registros, a cada uno de los cuales se puede acceder como entidades completas. Esencialmente, deberíamos imaginar varias matrices del mismo tamaño donde se pueda acceder a los elementos correspondientes en paralelo. Esta estructura de datos puede ofrecer operaciones de búsqueda de elementos relativamente rápidas si se ordena una de sus matrices, ya que podemos acceder a los elementos correspondientes en el mismo índice que el elemento encontrado.

Se puede implementar un array paralela utilizando diferentes métodos. En este caso, elegimos el contenedor STL std::vector, como el más fácil para explicar mejor el concepto.

Definimos una clase ParallelArray para almacenar solo dos matrices de tipos concretos (string e int) para simplificar la implementación. La clase incluye dos miembros de datos private de tipos std::vector que almacenan el contenido de la estructura de datos. Se define un solo constructor para aceptar el tamaño esperado de los arrays internas e invocar la función std::vector::reserve para asignar suficiente memoria antes de tiempo. Tenga en cuenta que este parámetro es opcional y tiene el valor predeterminado: 20.

Una vez que inicializamos el objeto de tipo ParallelArray, necesitamos insertar datos en él usando la función miembro push_back, que llama a la función miembro correspondiente con el mismo nombre para ambos miembros vector - v1 y v2. También definimos una función miembro llamada size para recuperar el número actual de elementos en el objeto ParallelArray.

La clase también tiene el operador [] definido para acceder a los elementos almacenados en la estructura. operator[] devuelve el valor std::pair<string, int> ya que tenemos matrices con tipos de datos fijos en nuestro ParallelArray. Alternativamente, se puede construir la plantilla de clase para aceptar múltiples tipos genéricos para inicializar los objetos vectoriales internos y reescribir las funciones miembro en consecuencia. Si la clase declara más de dos miembros de datos vectoriales internos, operator[] puede devolver los elementos con el método std::make_tuple de STL.

#include <iostream>
#include <string>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;

class ParallelArray {
 public:
  explicit ParallelArray(size_t size = 20) {
    v1.reserve(size);
    v2.reserve(size);
  };

  void push_back(string &d1, int d2);
  size_t size();
  std::pair<string, int> operator[](size_t pos);

 private:
  vector<string> v1;
  vector<int> v2;
};

void ParallelArray::push_back(string &d1, int d2) {
  v1.push_back(d1);
  v2.push_back(d2);
}

std::pair<string, int> ParallelArray::operator[](size_t pos) {
  if (pos <= v1.size()) {
    return std::make_pair(v1[pos], v2[pos]);
  } else {
    return std::make_pair("null", -1);
  }
}

size_t ParallelArray::size() { return v1.size(); }

template <typename T1, typename T2>
void printPair(const std::pair<T1, T2> &pp) {
  cout << "{" << pp.first << "," << pp.second << "}" << endl;
}

int main() {
  ParallelArray pa1;

  vector<string> data_set1 = {"Precise", "Quantal", "Saucy", "Raring"};

  vector<int> data_set2 = {11, 22, 33, 44};

  for (size_t i = 0; i < data_set1.size(); ++i) {
    pa1.push_back(data_set1[i], data_set2[i]);
  }

  for (size_t i = 0; i < pa1.size(); ++i) {
    printPair(pa1[i]);
  }

  return EXIT_SUCCESS;
}

Producción :

{Precise,11}
{Quantal,22}
{Saucy,33}
{Raring,44}

En ambos fragmentos de código, implementamos el código del controlador básico como parte de la función main para construir el objeto ParallelArray y luego imprimimos el contenido de la clase. La función auxiliar printPair se utiliza para mostrar los valores de los objetos std::pair en la consola.

Además, podemos agregar la función miembro pop_back para eliminar los elementos almacenados del final de cada miembro de datos vector. La función pop_back no acepta parámetros e invoca la función std::vector::pop_back. El uso de esta última función se demuestra en el siguiente ejemplo de código.

#include <iostream>
#include <string>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;

class ParallelArray {
 public:
  explicit ParallelArray(size_t size = 20) {
    v1.reserve(size);
    v2.reserve(size);
  };

  void push_back(string &d1, int d2);
  void pop_back();
  size_t size();
  std::pair<string, int> operator[](size_t pos);

 private:
  vector<string> v1;
  vector<int> v2;
};

void ParallelArray::push_back(string &d1, int d2) {
  v1.push_back(d1);
  v2.push_back(d2);
}

std::pair<string, int> ParallelArray::operator[](size_t pos) {
  if (pos <= v1.size()) {
    return std::make_pair(v1[pos], v2[pos]);
  } else {
    return std::make_pair("null", -1);
  }
}

size_t ParallelArray::size() { return v1.size(); }

void ParallelArray::pop_back() {
  v1.pop_back();
  v2.pop_back();
}

template <typename T1, typename T2>
void printPair(const std::pair<T1, T2> &pp) {
  cout << "{" << pp.first << "," << pp.second << "}" << endl;
}

int main() {
  ParallelArray pa1;

  vector<string> data_set1 = {"Precise", "Quantal", "Saucy", "Raring"};

  vector<int> data_set2 = {11, 22, 33, 44};

  for (size_t i = 0; i < data_set1.size(); ++i) {
    pa1.push_back(data_set1[i], data_set2[i]);
  }

  for (size_t i = 0; i < pa1.size(); ++i) {
    printPair(pa1[i]);
  }

  pa1.pop_back();
  pa1.pop_back();

  cout << "------------------------" << endl;
  for (size_t i = 0; i < pa1.size(); ++i) {
    printPair(pa1[i]);
  }

  return EXIT_SUCCESS;
}

Producción :

{Precise,11}
{Quantal,22}
{Saucy,33}
{Raring,44}
------------------------
{Precise,11}
{Quantal,22}
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Artículo relacionado - C++ Array