在C++中创建一个用户定义的向量数组来创建一个用户定义的矩阵

368yc8dk  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(189)

如何使用my_vector类创建my_matrix?我创建了一个具有标量积,加法,点积功能等的vector类。现在我想创建一个使用vector作为列的矩阵类。

my_vector.h

  1. #pragma once
  2. #include <cassert>
  3. #include <cmath>
  4. #include <cstddef>
  5. #include <initializer_list>
  6. #include <stdexcept>
  7. using namespace std;
  8. inline auto& lengtherr = "Not compatible";
  9. template <typename T>
  10. class my_vector
  11. {
  12. private :
  13. size_t m_dim;
  14. T *m_arr;
  15. public:
  16. my_vector(size_t s = 0) : m_dim{s}, m_arr{new T[s]} {}
  17. my_vector(const my_vector &rhs) : m_dim{rhs.m_dim},m_arr{new T [rhs.m_dim]}
  18. {
  19. for(int i = 0 ; i<rhs.m_dim;++i)m_arr[i] = rhs.m_arr[i];
  20. }
  21. my_vector(initializer_list<T> list): my_vector(list.size())
  22. {
  23. m_dim = list.size();
  24. int cnt = 0;
  25. for(auto i : list)
  26. m_arr[cnt++] = i;
  27. }
  28. ~my_vector() { delete[] m_arr; }
  29. size_t dim() const { return m_dim; }
  30. void operator=(const my_vector<T> &v)
  31. {
  32. if(v.dim()== m_dim)
  33. {
  34. for(int i = 0 ; i < m_dim;++i)
  35. m_arr[i] = v[i];
  36. }
  37. else
  38. throw length_error(lengtherr);
  39. }
  40. T &operator[](size_t idx)
  41. {
  42. assert(idx<m_dim);
  43. return m_arr[idx];
  44. }
  45. const T& operator[](size_t idx)const
  46. {
  47. assert(idx<m_dim);
  48. return m_arr[idx];
  49. }
  50. T length()
  51. {
  52. T temp;temp = m_arr[0]*m_arr[0];
  53. for(int i = 1 ; i< m_dim;++i)temp+= m_arr[i]*m_arr[i];
  54. return sqrt(temp);
  55. }
  56. void normalize()
  57. {
  58. T len = 1/(this->length());
  59. *this = *this * len;
  60. }
  61. };

字符串
这是my_matrix类

my_matrix. h

  1. template<typename T>
  2. class my_matrix
  3. {
  4. size_t m_row{0};
  5. size_t m_col{0};
  6. public : my_vector<T> *m_mat;
  7. my_matrix(size_t r, size_t c) : m_row{r},m_col{c}
  8. {
  9. /*How do I construct??*/
  10. }
  11. ~my_matrix()
  12. {
  13. /*destructor*/
  14. }
  15. };


我试图做的是创建my_matrix,并将my_vectors作为列,但如何在动态分配内存给my_matrix时控制my_vector长度?

fkvaft9z

fkvaft9z1#

我要做的第一件事是:

  1. my_vector<my_vector<T>> m_mat;

字符串
使用vector类来存储vector的vector。
一般的规则是,你不想管理所有的资源,你想在专门管理资源的类中管理资源,其他类使用它们。
也就是说,你的matrix类应该使用 some other class 来管理它的内存使用。
这个矩阵是向量的向量可以工作,但它会导致记忆碎片。
因此,第二次迭代将涉及编写一个vector_view,它 Package 了一块连续内存,但不拥有它。

  1. std::vector<T> m_mat_data;


列的大小是该数据块的vector_view s。
使用向量视图与之交互的连续缓冲区提供了很好的性能,因为您避免了多次分配,获得了连续内存,并在执行中间工作时避免了不必要的分配。
当然,让它工作得很好需要一点技巧,你的my_vector甚至没有const长度方法,这证明你缺乏足够的C++经验来使它变得容易。
向量的向量解决方案在你的技能水平上更容易使用,并且应该给你给予足够好的体验。在编写这个的contiguous-with-views变体时,我经常会编写更简单的容器的容器版本来验证我更有效和复杂的版本。
所以写vector的vector版本就开始了。

  1. public : my_vector<my_vector<T>> m_mat;
  2. my_matrix(size_t r, size_t c) :
  3. m_row{r},
  4. m_col{c},
  5. m_mat(m_col) // you have m_col number of columns
  6. {
  7. for( size_t i = 0; i < m_col; ++i )
  8. m_mat[i] = my_vector<T>(m_row); // the columns are m_row long
  9. }


现在,std::vector<T>有一个双参数构造函数size, T,如果你把它添加到my_vector,你会得到一个稍微干净的解决方案:

  1. public : my_vector<my_vector<T>> m_mat;
  2. my_matrix(size_t r, size_t c) :
  3. m_row{r},
  4. m_col{c},
  5. m_mat(m_col, my_vector<T>(m_row))
  6. {
  7. }


对于视图情况:

  1. template<class T>
  2. struct my_vector_view {
  3. T* m_data = nullptr;
  4. std::size_t length = 0u;
  5. my_vector_view(T* s, T* e):my_vector_view(s, e-s) {}
  6. my_vector_view(T* s, std::size_t l):m_data(s), length(l) {}
  7. my_vector_view() {}
  8. T& operator[](std::size_t i)& { return m_data[i]; }
  9. T const& operator[](std::size_t i) const& { return m_data[i]; }
  10. T operator[](std::size_t i) && { return std::move(m_data[i]); }
  11. // etc
  12. };


然后

  1. template<class T>
  2. struct matrix {
  3. std::size_t m_row = 0;
  4. std::size_t m_col = 0;
  5. std::vector<T> m_data;
  6. my_vector_view<T> operator[](std::size_t i)& {
  7. return { m_data.data()+i*m_row, m_row };
  8. }
  9. // etc
  10. };


这里matrix[i]返回列向量的视图,matrix[i][j]返回矩阵的单个元素。
我们甚至可以用class stride=std::integral_constant<std::size_t, 1>来扩充vector_view,并且也有行向量支持。

展开查看全部

相关问题