Parallel Array Data Structure in C++
This article will demonstrate how to implement a parallel array data structure in C++.
Use the std::vector
Container to Implement a Custom Parallel Array Class in C++
A parallel array is the abstract data structure that implements an array of multiple records, each of which can be accessed as whole entities. Essentially, we should imagine multiple same-sized arrays where corresponding elements can be accessed in parallel. This data structure can offer relatively fast element search operations if one of its arrays is sorted since we can access corresponding elements on the same index as the found element.
A parallel array can be implemented using different methods. In this case, we chose std::vector
STL container - as the easiest one to better explain the concept.
We define a ParallelArray
class to store only two arrays of concrete types (string
and int
) to simplify the implementation. The class includes two private
data members of std::vector
types that store the data structure contents. A single constructor is defined to accept the expected size of the internal arrays and invoke std::vector::reserve
function to allocate enough memory ahead of time. Notice that this parameter is optional and has the default value - 20
.
Once we initialize the object of type ParallelArray
, we need to push data into it using the push_back
member function, which calls the corresponding member function with the same name for both vector
members - v1
and v2
. We also defined a member function called size
to retrieve the current number of elements in the ParallelArray
object.
The class also has the []
operator defined to access stored elements in the structure. operator[]
returns std::pair<string, int>
value since we have arrays with fixed data types in our ParallelArray
. Alternatively, one can construct the class template to accept multiple generic types to initialize the internal vector
objects and rewrite member functions accordingly. If the class declares more than two internal vector
data members, operator[]
can return the elements with the std::make_tuple
method from 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;
}
Output:
{Precise,11}
{Quantal,22}
{Saucy,33}
{Raring,44}
In both code snippets, We implement the basic driver code as part of the main
function to construct the ParallelArray
object and then print the contents of the class. printPair
helper function is utilized to display the values of std::pair
objects to console.
Additionally, we can add pop_back
member function to remove the stored elements from the end of each vector
data member. pop_back
function accepts no parameters and invokes the std::vector::pop_back
function. The usage of the latter function is demonstrated in the following code example.
#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;
}
Output:
{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