Estrutura de dados de array paralela em C++

Jinku Hu 12 outubro 2023
Estrutura de dados de array paralela em C++

Este artigo demonstrará como implementar uma estrutura de dados de array paralela em C++.

Use o recipiente std::vector para implementar uma classe de array paralelo personalizado em C++

um array paralela é a estrutura de dados abstrata que implementa um array de vários registros, cada um dos quais pode ser acessado como entidades inteiras. Essencialmente, devemos imaginar vários arrays do mesmo tamanho, onde os elementos correspondentes podem ser acessados ​​em paralelo. Essa estrutura de dados pode oferecer operações de pesquisa de elemento relativamente rápidas se um de seus arrays for classificado, pois podemos acessar os elementos correspondentes no mesmo índice do elemento encontrado.

um array paralela pode ser implementada usando métodos diferentes. Neste caso, escolhemos o container STL std::vector - como o mais fácil para explicar melhor o conceito.

Definimos uma classe ParallelArray para armazenar apenas dois arrays de tipos concretos (string e int) para simplificar a implementação. A classe inclui dois membros de dados private de tipos std::vector que armazenam o conteúdo da estrutura de dados. Um único construtor é definido para aceitar o tamanho esperado dos arrays internos e invocar a função std::vector::reserve para alocar memória suficiente com antecedência. Observe que este parâmetro é opcional e possui o valor padrão - 20.

Depois de inicializarmos o objeto do tipo ParallelArray, precisamos inserir dados nele usando a função de membro push_back, que chama a função de membro correspondente com o mesmo nome para ambos os membros vetor - v1 e v2. Também definimos uma função de membro chamada size para recuperar o número atual de elementos no objeto ParallelArray.

A classe também possui o operador [] definido para acessar os elementos armazenados na estrutura. operator[] retorna o valor std::pair<string, int> uma vez que temos arrays com tipos de dados fixos em nosso ParallelArray. Alternativamente, pode-se construir o modelo de classe para aceitar vários tipos genéricos para inicializar os objetos vector internos e reescrever as funções de membro de acordo. Se a classe declara mais de dois membros de dados vector internos, operator[] pode retornar os elementos com o 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;
}

Produção:

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

Em ambos os trechos de código, implementamos o código do driver básico como parte da função main para construir o objeto ParallelArray e depois imprimir o conteúdo da classe. A função auxiliar printPair é utilizada para exibir os valores dos objetos std::pair para o console.

Além disso, podemos adicionar a função de membro pop_back para remover os elementos armazenados do final de cada membro de dados vector. A função pop_back não aceita parâmetros e invoca a função std::vector::pop_back. O uso da última função é demonstrado no exemplo de código a seguir.

#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;
}

Produção:

{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

Artigo relacionado - C++ Array