БлогNot. Двумерные матрицы из pair, vector, map и set

Двумерные матрицы из pair, vector, map и set

В этой заметке мы уже делали двумерную матрицу из обычного контейнера vector, применяя "вектор векторов" - ведь шаблон вектора применим к любому типу данных, в том числе, и к другому контейнеру.

Однако делать так необязательно, всегда можно использовать замечательный класс pair, представляющий собой шаблон для пары значений любого типа данных. При этом "пары" могут вкладываться друг в друга, что позволит создать контейнер любой нужной нам сложности.

Например, пара индексов элементов двумерной матрицы может быть описана как

pair<int, int>

Если "прицепить" к индексам ещё и значение любого нужного типа данных (пусть будет тоже int), получаем структуру

pair<pair<int, int>, int>

для одного элемента целочисленной матрицы, ну а затем можно "сложить" эти элементы в любой удобный контейнер, допустим, в тот же vector:

vector <pair<pair<int, int>, int>> matrix;

Если знать, что образовать пару можно функцией make_pair (first,second), а обращаться к первому и второму членам пары через свойства first и second, работать с контейнером, составленным из пар, становится очень удобно.

В прилагаемой программе показано формирование данных для двумерной целочисленной матрицы на основе трёх самых популярных контейнеров - vector, map и set.

Так как у нас элементы везде одни и те же (1,2,3,...), они корректно запишутся во все три контейнера, на самом деле, выбор контейнера зависит от условия задачи, например, во множество уже встроен контроль уникальности его элементов.

Проверено в консолях Visual Studio 2015 и QT 5.X.

#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iterator>
using namespace std;

template <class T>
struct printStringIntMap : public unary_function<T, void> {
 ostream & ostr;
 printStringIntMap(ostream &stream) : ostr(stream) {}

 void operator()(const T& item) const {
  ostr << "(" << item.first << ")" << "=" << item.second << endl;
 }
};

int main() {
 //Матрица на основе контейнера vector
 vector <pair<pair<int, int>, int>> matrix;
 const int n = 4, m = 3;
 for (int i = 0; i<n*m; i++) matrix.push_back(make_pair(make_pair(i / m, i%m), i + 1));
 vector <pair<pair<int, int>, int>>::iterator it = matrix.begin();
 for (int i = 0; i < n; i++) {
  for (int j = 0; j < m; j++) cout << setw(3) << (it++)->second
   << "(" << setw(1) << i << "," << setw(1) << j << ") ";
  cout << endl;
 }

 //Она же на map
 map <string, int> matrix2;
 for (int i = 0; i<n*m; i++) {
  string index = to_string(i / m) + "_" + to_string(i%m);
  matrix2.insert(pair<string, int>(index, i + 1));
 }
 map <string, int>::iterator it2;
 for (it2 = matrix2.begin(); it2 != matrix2.end(); ++it2)
  cout << it2->first << ": " << it2->second << endl;

 //Она же на set - будет контроль уникальности элементов
 set <pair<string, int>> matrix3;
 for (int i = 0; i<n*m; i++) {
  matrix3.insert(pair<string, int>(to_string(i / m) + "_" + to_string(i%m), i + 1));
 }
 for_each(matrix3.begin(), matrix3.end(),
  printStringIntMap<map <string, int>::value_type>(cout));

 cin.get(); return 0;
}

Примечания

1. Для вывода в консоль элементов множества set пришлось делать отдельный класс printStringIntMap.

2. Выводить первую матрицу, сделанную на основе контейнера vector, в консоль было необязательно в двойном цикле, можно было обойтись и одним:

vector <pair<pair<int, int>, int>>::iterator it;
 for (it=matrix.begin(); it<matrix.end(); ++it)
  cout << "matrix[" << it->first.first << "," << 
  it->first.second << "]=" << it->second << endl;

3. Обратите внимание, как заполнить двумерную матрицу последовательно идущими значениями 1,2,3,... , применяя только один цикл, приём применим и к "обычной" двумерной матрице:

#include <iostream>
#include <iomanip>
using namespace std;

int main() {
 const int n = 4, m = 3;
 int a[n][m];

 //Заполняем матрицу одним циклом
 for (int i = 0; i<n*m; i++) a[i/m][i%m] = i+1;
 
 //Выводим обычным двойным циклом
 for (int i = 0; i < n; i++) {
  for (int j = 0; j<m; j++) cout << setw(3) << a[i][j] << " ";
  cout << endl;
 }

 cin.get(); return 0;
}

теги: c++ программирование список

07.05.2019, 16:58; рейтинг: 37

  свежие записипоиск по блогукомментариистатистикао "вирусах" в архивах .zip

Наверх Яндекс.Метрика
© PerS
вход