Parallele Array-Datenstruktur in C++

Jinku Hu 12 Oktober 2023
Parallele Array-Datenstruktur in C++

In diesem Artikel wird veranschaulicht, wie eine parallele Array-Datenstruktur in C++ implementiert wird.

Verwendung des std::vector-Containers zur Implementierung einer eigenen parallelen Array-Klasse in C++

Ein paralleles Array ist die abstrakte Datenstruktur, die ein Array aus mehreren Datensätzen implementiert, auf die jeweils als ganze Entitäten zugegriffen werden kann. Im Wesentlichen sollten wir uns mehrere gleich große Arrays vorstellen, in denen auf entsprechende Elemente parallel zugegriffen werden kann. Diese Datenstruktur kann relativ schnelle Elementsuchoperationen bieten, wenn eines ihrer Arrays sortiert ist, da wir auf entsprechende Elemente auf demselben Index wie das gefundene Element zugreifen können.

Ein paralleles Array kann mit verschiedenen Methoden implementiert werden. In diesem Fall haben wir den STL-Container std::vector gewählt - als der einfachste, um das Konzept besser zu erklären.

Wir definieren eine ParallelArray-Klasse, um nur zwei Arrays konkreter Typen (string und int) zu speichern, um die Implementierung zu vereinfachen. Die Klasse enthält zwei private Datenmember von std::vector-Typen, die den Inhalt der Datenstruktur speichern. Ein einzelner Konstruktor ist so definiert, dass er die erwartete Größe der internen Arrays akzeptiert und die Funktion std::vector::reserve aufruft, um im Voraus genügend Speicher zuzuweisen. Beachten Sie, dass dieser Parameter optional ist und den Standardwert 20 hat.

Sobald wir das Objekt vom Typ ParallelArray initialisiert haben, müssen wir Daten mit der Member-Funktion push_back hineinschieben, die die entsprechende Member-Funktion mit demselben Namen für beide Vektor-Member - v1 und v2 aufruft. . Wir haben auch eine Memberfunktion namens size definiert, um die aktuelle Anzahl von Elementen im ParallelArray-Objekt abzurufen.

Die Klasse hat auch den Operator [] definiert, um auf gespeicherte Elemente in der Struktur zuzugreifen. operator[] gibt den Wert std::pair<string, int> zurück, da wir Arrays mit festen Datentypen in unserem ParallelArray haben. Alternativ kann man die Klassenschablone so konstruieren, dass sie mehrere generische Typen akzeptiert, um die internen Vektor-Objekte zu initialisieren und die Memberfunktionen entsprechend umzuschreiben. Wenn die Klasse mehr als zwei interne vector-Datenelemente deklariert, kann operator[] die Elemente mit der Methode std::make_tuple aus STL zurückgeben.

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

Ausgabe:

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

In beiden Codeschnipseln implementieren wir den grundlegenden Treibercode als Teil der Funktion main, um das Objekt ParallelArray zu konstruieren und dann den Inhalt der Klasse auszugeben. Die Hilfsfunktion printPair wird verwendet, um die Werte von std::pair-Objekten auf der Konsole anzuzeigen.

Zusätzlich können wir die Member-Funktion pop_back hinzufügen, um die gespeicherten Elemente vom Ende jedes vector-Datenmembers zu entfernen. Die Funktion pop_back akzeptiert keine Parameter und ruft die Funktion std::vector::pop_back auf. Die Verwendung der letzteren Funktion wird im folgenden Codebeispiel demonstriert.

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

Ausgabe:

{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

Verwandter Artikel - C++ Array