Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«C++. Π‘Π±ΠΎΡ€Π½ΠΈΠΊ Ρ€Π΅Ρ†Π΅ΠΏΡ‚ΠΎΠ²Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 105

Автор Π”. БтСфСнс

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 11.28. matrix.hpp

#ifndef MATRIX_HPP

#define MATRIX_HPP


#include "stride_iter.hpp" // см. Ρ€Π΅Ρ†Π΅ΠΏΡ‚ 11.12

#include <valarray>

#include <numeric>

#include <algorithm>


template<class Value_T>

class matrix {

public:

 // ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ ΠΈΠΌΠ΅Π½Π°, Π²Π²ΠΎΠ΄ΠΈΠΌΡ‹Π΅ typedef

 typedef Value_T value_type;

 typedef matrix self;

 typedef value_type* iterator;

 typedef const value_type* const_iterator;

 typedef Value_T* row_type;

 typedef stride_iter<value_type*> col_type;

 typedef const value_type* const_row_type;

 typedef stride_iter<const value_type*> const_col_type;


 // конструкторы

 matrix() : nrows(0), ncols(0), m() {}

 matrix(int r, int c) : nrows(r), ncols(c), m(r * с) {}

 matrix(const self& x) : m(x.m), nrows(x.nrows), ncols(x.ncols) {}

 template<typename T>

 explicit matrix(const valarray<T>& x)

  : m(x.size() + 1), nrows(x.size()), ncols(1) {

  for (int i=0; i<x.size(); ++i) m[i] = x[i];

 }

 // ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ΡŒ конструированиС ΠΈΠ· ΠΌΠ°Ρ‚Ρ€ΠΈΡ† Π΄Ρ€ΡƒΠ³ΠΈΡ… Ρ‚ΠΈΠΏΠΎΠ²

 template<typename T> explicit matrix(const matrix<T>& x)

  : m(x.size() + 1), nrows(x.nrows), ncols(x.ncols) {

  copy(x.begin(), x.end(), m.begin());

 }


// ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

 int rows() const { return nrows; }

 int cols() const { return ncols; }

 int size() const { return nrows * ncols; }


 // доступ ΠΊ элСмСнтам

 row_type row begin(int n) { return &m[n * cols()]; }

 row_type row_end(int n) { return row_begin() + cols(); }

 col_type col_begin(int n) { return col_type(&m[n], cols()); }

 col_type col_end(int n) { return col_begin(n) + cols(); }

 const_row_type row_begin(int n) const { return &m[n * cols()]; }

 const_row_type row_end(int n) const { return row_begin() + cols(); }

 const_col_type col_begin(int n) const { return col_type(&m[n], cols()); }

 const_col_type col_end(int n) const { return col_begin() + cols(); }

 iterator begin() { return &m[0]; }

 iterator end() { return begin() + size(); }

 const_iterator begin() const { return &m[0]; }

 const_iterator end() const { return begin() + size(); }


 // ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹

 self& operator=(const self& x) {

  m = x.m;

  nrows = x.nrows;

  ncols = x.ncols;

  return *this;

 }

 self& operator=(value_type x) { m = x; return *this; }

 row_type operator[](int n) { return row_begin(n); }

 const_row_type operator[](int n) const { return row_begin(n); }

 self& operator+=(const self& x) { m += x.m; return *this; }

 self& operator-=(const self& x) { m -= x.m; return *this; }

 self& operator+=(value_type x) { m += x; return *this; }

 self& operator-=(value_type x) { m -= x; return *this; }

 self& operator*=(value_type x) { m *= x; return *this; }

 self& operator/=(value_type x) { m /= x; return *this; }

 self& operator%=(value_type x) { m %= x; return *this; }

 self operator-() { return -m; }

 self operator+() { return +m; }

 self operator!() { return !m; }

 self operator~() { return ~m; }


 // друТСствСнныС ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹

 friend self operator+(const self& x, const self& y) { return self(x) += y; }

 friend self operator-(const self& x, const self& y) { return self(x) -= y; }

 friend self operator+(const self& x, value_type y) { return self(x) += y; }

 friend self operator-(const self& x, value_type y) { return self(x) -= y; }

 friend self operator*(const self& x, value type y) { return self(x) *= y; }

 friend self operator/(const self& x, value_type y) { return self(x) /= y; }

 friend self operator%(const self& x, value_type y) { return self(x) %= y; }

private:

 mutable valarray<Value_T> m;

 int nrows;

 int ncols;

};

#endif

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 11.29 ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡˆΠ°Π±Π»ΠΎΠ½Π½Ρ‹ΠΉ класс matrix.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 11.29. ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ шаблона matrix

#include "matrix.hpp"

#include <iostream>


using namespace std;


int main() {

 matrix<int> m(2,2);

 m = 0;

 m[0][0] = 1;

 m[1][1] = 1;

 m *= 2;

 cout << "(" << m[0][0] << "," << m[0][1] << ")" << endl;

 cout << "(" << m[1][0] << "," << m[1][1] << ")" << endl;

}

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° 11.29 Π²Ρ‹Π΄Π°Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚.

(2,0)

(0,2)

ΠžΠ±ΡΡƒΠΆΠ΄Π΅Π½ΠΈΠ΅

ΠŸΡ€ΠΎΠ΅ΠΊΡ‚ шаблона ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Ρ‹, прСдставлСнный Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 11.28, Π² Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ стСпСни инспирирован шаблоном ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Ρ‹ Π‘ΡŒΠ΅Ρ€Π½Π° Бтрауструпа (Bjarne Stroustrup) ΠΈΠ· Π΅Π³ΠΎ ΠΊΠ½ΠΈΠ³ΠΈ Β«The C++ Programming LanguageΒ», 3-Π΅ ΠΈΠ·Π΄Π°Π½ΠΈΠ΅ (ΠΈΠ·Π΄Π°Ρ‚Π΅Π»ΡŒΡΡ‚Π²ΠΎ Β«Addison WesleyΒ»). РСализация Бтрауструпа отличаСтся Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Π΅Π³ΠΎ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ класс slice ΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° valarray для индСксации. РСализованная Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 11.27 ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ вмСсто Π½ΠΈΡ… ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ с шагом ΠΈΠ· Ρ€Π΅Ρ†Π΅ΠΏΡ‚Π° 11.12, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚Π½Ρ‹ΠΌΠΈ ΠΈ ΠΏΡ€ΠΈ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… рСализациях Π±ΠΎΠ»Π΅Π΅ эффСктивными.

Π¨Π°Π±Π»ΠΎΠ½Π½Ρ‹ΠΉ класс matrix позволяСт ΠΈΠ½Π΄Π΅ΠΊΡΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ элСмСнт i-ΠΉ строки ΠΈ j-Π³ΠΎ столбца, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ Π΄Π²ΠΎΠΉΠ½ΠΎΠΉ индСксации. НапримСр:

matrix<int> m(100,100);

cout << "the element at row 24 and column 42 is " << m[24][42] << endl;

Π¨Π°Π±Π»ΠΎΠ½Π½Ρ‹ΠΉ класс matrix Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρ‹ begin ΠΈ end, Ρ‚.Π΅. Π΅Π³ΠΎ Π»Π΅Π³ΠΊΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ°Ρ… STL.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 11.28 содСрТит строку, которая, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρƒ вас Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΡƒΠ΄ΠΈΠ²Π»Π΅Π½ΠΈΠ΅. Π˜ΠΌΠ΅Π΅Ρ‚ΡΡ Π² Π²ΠΈΠ΄Ρƒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ объявлСниС.

mutable valarray<Value_T> m;

ОбъявлСниС поля-Ρ‡Π»Π΅Π½Π° m со спСцификатором mutable Π²Ρ‹Π½ΡƒΠΆΠ΄Π΅Π½Π½ΠΎ. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС я Π½Π΅ ΠΌΠΎΠ³ Π±Ρ‹ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ со спСцификатором const, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ нСльзя ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ для const valarray.

Π‘ΠΌΠΎΡ‚Ρ€ΠΈ Ρ‚Π°ΠΊΠΆΠ΅

Π Π΅Ρ†Π΅ΠΏΡ‚Ρ‹ 11.15 ΠΈ 11.16.

11.15. РСализация статичСской ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Ρ‹

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ°

ВрСбуСтся эффСктивно Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Ρƒ, ΠΊΠΎΠ³Π΄Π° Π΅Π΅ Ρ€Π°Π·ΠΌΠ΅Ρ€Π½ΠΎΡΡ‚ΡŒ (Ρ‚.Π΅. количСство строк ΠΈ столбцов) постоянна ΠΈ извСстна Π½Π° этапС компиляции.

РСшСниС

Когда Ρ€Π°Π·ΠΌΠ΅Ρ€Π½ΠΎΡΡ‚ΡŒ ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Ρ‹ извСстна Π½Π° этапС компиляции, компилятор ΠΌΠΎΠΆΠ΅Ρ‚ Π»Π΅Π³ΠΊΠΎ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ количСство строк ΠΈ столбцов задаСтся Π² Π²ΠΈΠ΄Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² шаблона, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 11.30.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 11.30. kmatrix.hpp

#ifndef KMATRIX_HPP

#define KMATRIX_HPP


#include "kvector.hpp"

#include "kstride_iter.hpp"


template<class Value_T, int Rows_N, int Cols_N>

class kmatrix {

public:

 // ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ ΠΈΠΌΠ΅Π½Π°, Π²Π²ΠΎΠ΄ΠΈΠΌΡ‹Π΅ typedef

 typedef Value_T value_type;

 typedef kmatrix self;

 typedef Value_T* iterator;

 typedef const Value_T* const_iterator;

 typedef kstride_iter<Value_T*, 1> row_type;

 typedef kstride_iter<Value_T*, Cols_N> col_type;

 typedef kstride_iter<const Value_T*, 1> const_row_type;

 typedef kstride_iter<const Value T*, Cols_N> const_col_type;


 // ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ константы

 static const int nRows = Rows_N;

 static const int nCols = Cols_N;


 // конструкторы

 kmatrix() { m = Value_T(); }

 kmatrix(const self& x) { m = x.m; }

 explicit kmatrix(Value_T& x) { m = x.m; }


 // ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

 static int rows() { return Rows_N; }

 static int cols() { return Cols_N; }

 row_type row(int n) { return row_type(begin() * (n * Cols_N)); }

 col_type col(int n) { return col_type(begin() + n); }

 const_row_type row(int n) const {

  return const_row_type(begin() + (n * Cols_N));

 }

 const_col_type col(int n) const {

  return const_col_type(begin() + n);

 }

 iterator begin() { return m.begin(); }

 iterator end() { return m.begin() + size(); }

 const_iterator begin() const { return m; }

 const_iterator end() const { return m + size(); }

 static int size() { return Rows_N * Cols_N; }


 // ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹

 row_type operator[](int n) { return row(n); }

 const_row_type operator[](int n) const { return row(n); }


 // ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ присваивания

 self& operator=(const self& x) { m = x.m; return *this; }

 self& operator=(value_type x) { m = x; return *this; }

 self& operator+=(const self& x) { m += x.m; return *this; }

 self& operator-=(const self& x) { m -= x.m; return *this; }

 self& operator+={value_type x) { m += x; return *this; }

 self& operator-=(value_type x) { m -= x; return *this; }

 self& operator*=(value_type x) { m *= x; return *this; }

 self& operator/=(value_type x) { m /= x; return *this; }

 self operator-() { return self(-m); }


 // Π΄Ρ€ΡƒΠ·ΡŒΡ

 friend self operator+(self x, const self& Ρƒ) { return x += y; }

 friend self operator-(self x, const self& y) { return x -= y; }

 friend self operator+(self x, value_type y) { return x += y; }

 friend self operator-(self x, value type y) { return x -= y; }

 friend self operator*(self x, value_type y) { return x *= y; }

 friend self operator/(self x, value_type y) { return x /= y; }

 friend bool operator==(const self& x, const self& y) { return x == y; }

 friend bool operator!=(const self& x, const self& y) { return x.m != y.m; }

private:

 kvector<Value_T, (Rows_N + 1) * Cols_N> m;

};


#endif

Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 11.31 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, Π΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΡƒΡŽΡ‰Π°Ρ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ шаблонного класса kmatrix.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 11.31. ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ kmatrix

#include "kmatrix.hpp"

#include <iostream>


using namespace std;


template<class Iter_T>

void outputRowOrColumn(Iter_T iter, int n) {

 for (int i=0; i < n; ++i) {

  cout << iter[i] << " ";