Structure de données de tableau parallèle en C++

Jinku Hu 12 octobre 2023
Structure de données de tableau parallèle en C++

Cet article montrera comment implémenter une structure de données de tableau parallèle en C++.

Utilisez le conteneur std::vector pour implémenter une classe de tableau parallèle personnalisé en C++

Un tableau parallèle est la structure de données abstraite qui implémente un tableau de plusieurs enregistrements, chacun étant accessible en tant qu’entités entières. Essentiellement, nous devrions imaginer plusieurs tableaux de même taille où les éléments correspondants peuvent être accessibles en parallèle. Cette structure de données peut offrir des opérations de recherche d’éléments relativement rapides si l’un de ses tableaux est trié car nous pouvons accéder aux éléments correspondants sur le même index que l’élément trouvé.

Un tableau parallèle peut être implémenté en utilisant différentes méthodes. Dans ce cas, nous avons choisi le conteneur STL std::vector - comme le plus simple pour mieux expliquer le concept.

Nous définissons une classe ParallelArray pour ne stocker que deux tableaux de types concrets (string et int) pour simplifier la mise en œuvre. La classe comprend deux membres de données private de types std::vector qui stockent le contenu de la structure de données. Un seul constructeur est défini pour accepter la taille attendue des tableaux internes et invoquer la fonction std::vector::reserve pour allouer suffisamment de mémoire à l’avance. Notez que ce paramètre est facultatif et a la valeur par défaut - 20.

Une fois que nous avons initialisé l’objet de type ParallelArray, nous devons y insérer des données à l’aide de la fonction membre push_back, qui appelle la fonction membre correspondante avec le même nom pour les deux membres vector - v1 et v2. Nous avons également défini une fonction membre appelée size pour récupérer le nombre actuel d’éléments dans l’objet ParallelArray.

La classe a également l’opérateur [] défini pour accéder aux éléments stockés dans la structure. operator[] renvoie la valeur std::pair<string, int> puisque nous avons des tableaux avec des types de données fixes dans notre ParallelArray. Alternativement, on peut construire le modèle de classe pour accepter plusieurs types génériques pour initialiser les objets vector internes et réécrire les fonctions membres en conséquence. Si la classe déclare plus de deux données membres internes vector, operator[] peut retourner les éléments avec la méthode 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;
}

Production:

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

Dans les deux extraits de code, nous implémentons le code du pilote de base dans le cadre de la fonction main pour construire l’objet ParallelArray, puis imprimer le contenu de la classe. La fonction d’assistance printPair est utilisée pour afficher les valeurs des objets std::pair à la console.

De plus, nous pouvons ajouter la fonction membre pop_back pour supprimer les éléments stockés à la fin de chaque membre de données vector. La fonction pop_back n’accepte aucun paramètre et invoque la fonction std::vector::pop_back. L’utilisation de cette dernière fonction est illustrée dans l’exemple de code suivant.

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

Production:

{Precise,11}
{Quantal,22}
{Saucy,33}
{Raring,44}
------------------------
{Precise,11}
{Quantal,22}
Auteur: 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

Article connexe - C++ Array