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