【问题标题】:Vector of Vectors to create matrix向量的向量来创建矩阵
【发布时间】:2012-09-04 17:32:02
【问题描述】:

我正在尝试输入二维矩阵的维度。然后使用用户输入来填充这个矩阵。我尝试这样做的方法是通过向量(向量的向量)。但是每当我尝试读取数据并将其附加到矩阵时,都会遇到一些错误。

//cin>>CC; cin>>RR; already done
vector<vector<int> > matrix;
for(int i = 0; i<RR; i++)
{
    for(int j = 0; j<CC; j++)
    {
    cout<<"Enter the number for Matrix 1";
         cin>>matrix[i][j];
    }
}

每当我尝试这样做时,它都会给我一个下标超出范围的错误。有什么建议吗?

【问题讨论】:

  • 你没有初始化matrix
  • @elyashiv 实际上,matrix 已初始化。
  • @Luchian Grigore 向量最初是空的。因此,超出范围错误。
  • 正确。作为一个长度为零的向量,包含一个长度为零的向量 =)
  • @lcfseth 这样吗?这并不意味着它没有被初始化。它是一个大小为 0 的初始化向量对象。初始化在 C++ 中具有精确的含义。

标签: c++ vector matrix


【解决方案1】:

在访问任何元素之前,您必须将向量的向量初始化为适当的大小。你可以这样做:

// assumes using std::vector for brevity
vector<vector<int>> matrix(RR, vector<int>(CC));

这会创建一个RR 大小为CC 的向量,并用0 填充。

【讨论】:

  • +1:我也是这样做的。很惊讶你是唯一一个给出这个答案的人。顺便说一句,我永远不会使用向量的向量来表示矩阵。 =)
  • @paddy 我也不会使用它。能够随时任意调整任何列或行的大小,或者在创建后更改矩阵的尺寸,对我来说太可怕了。
  • 改变矩阵的维度是正常的(在 MatLab 中你总是这样做),但在实际使用中,矩阵是一个连续的块,你改变的只是行/ cols(基本上跟踪步长) - 要索引矩阵中的元素,您可以根据多维索引计算线性索引。
  • @paddy 我知道这很正常,但通常这是一个坏主意。我的矩阵有固定的大小,这大大减少了错误的范围。
  • @paddy 我的意思是我的矩阵的维度是矩阵的类型,所以它们不能改变。由于我将矩阵视为数学对象而不是存储空间,因此(对我而言)使用编译器来强制执行某些约束是有意义的,例如,不能将 2x4 矩阵分配给 5x1,或者不能将矩阵相乘没有兼容的尺寸。存储本身是一个单独的块,在我的情况下是静态分配的,因为我倾向于处理小矩阵,但可以很容易地适应动态分配而不影响类型安全。
【解决方案2】:

事实上,你的向量的两个维度都是 0。

相反,将向量初始化为:

vector<vector<int> > matrix(RR);
for ( int i = 0 ; i < RR ; i++ )
   matrix[i].resize(CC);

这将为您提供一个维度矩阵RR * CC,所有元素都设置为0

【讨论】:

  • 您可以在一个语句中创建大小为 CC 向量的大小为 RR 的向量,并避免调整大小。
  • @juanchopanza 你是在谈论 std::generate 还是只是赋值?
【解决方案3】:

我不熟悉 c++,但快速查看文档表明这应该可行:

//cin>>CC; cin>>RR; already done
vector<vector<int> > matrix;
for(int i = 0; i<RR; i++)
{
    vector<int> myvector;
    for(int j = 0; j<CC; j++)
    {
        int tempVal = 0;
        cout<<"Enter the number for Matrix 1";
        cin>>tempVal;
        myvector.push_back(tempVal);
    }
    matrix.push_back(myvector);
}

【讨论】:

  • 正确,但这会因随后的推回而受到性能损失。
  • @LuchianGrigore:从 std::cin 读取矩阵会扼杀你关于性能的争论
【解决方案4】:

假设我们有以下类:

#include <vector>

class Matrix {
 private:
  std::vector<std::vector<int>> data;
};

首先我想建议你实现一个默认构造函数:

#include <vector>

class Matrix {
 public:
  Matrix(): data({}) {}

 private:
  std::vector<std::vector<int>> data;
};

此时我们可以如下创建Matrix实例:

Matrix one;

下一个战略步骤是实现Reset 方法,该方法采用两个整数参数,分别指定矩阵的新行数和列数:

#include <vector>

class Matrix {
 public:
  Matrix(): data({}) {}

  Matrix(const int &rows, const int &cols) {
    Reset(rows, cols);
  }

  void Reset(const int &rows, const int &cols) {
    if (rows == 0 || cols == 0) {
      data.assign(0, std::vector<int>(0));
    } else {
      data.assign(rows, std::vector<int>(cols));
    }
  }

 private:
  std::vector<std::vector<int>> data;
};

此时Reset 方法将二维矩阵的维度更改为给定的维度并重置其所有元素。稍后让我告诉你为什么我们可能需要这个。

好吧,我们可以创建并初始化我们的矩阵:

Matrix two(3, 5);

让我们为矩阵添加信息方法:

#include <vector>

class Matrix {
 public:
  Matrix(): data({}) {}

  Matrix(const int &rows, const int &cols) {
    Reset(rows, cols);
  }

  void Reset(const int &rows, const int &cols) {
    data.resize(rows);
    for (int i = 0; i < rows; ++i) {
      data.at(i).resize(cols);
    }
  }

  int GetNumRows() const {
    return data.size();
  }

  int GetNumColumns() const {
    if (GetNumRows() > 0) {
      return data[0].size();
    }

    return 0;
  }

 private:
  std::vector<std::vector<int>> data;
};

此时我们可以得到一些琐碎的矩阵调试信息:

#include <iostream>

void MatrixInfo(const Matrix& m) {
  std::cout << "{ \"rows\": " << m.GetNumRows()
            << ", \"cols\": " << m.GetNumColumns() << " }" << std::endl;
}

int main() {
  Matrix three(3, 4);
  MatrixInfo(three);
}

此时我们需要的第二个类方法是At。一种获取我们私有数据的方法:

#include <vector>

class Matrix {
 public:
  Matrix(): data({}) {}

  Matrix(const int &rows, const int &cols) {
    Reset(rows, cols);
  }

  void Reset(const int &rows, const int &cols) {
    data.resize(rows);
    for (int i = 0; i < rows; ++i) {
      data.at(i).resize(cols);
    }
  }

  int At(const int &row, const int &col) const {
    return data.at(row).at(col);
  }

  int& At(const int &row, const int &col) {
    return data.at(row).at(col);
  }

  int GetNumRows() const {
    return data.size();
  }

  int GetNumColumns() const {
    if (GetNumRows() > 0) {
      return data[0].size();
    }

    return 0;
  }

 private:
  std::vector<std::vector<int>> data;
};

常量At方法取行号和列号,返回对应矩阵单元格中的值:

#include <iostream>

int main() {
  Matrix three(3, 4);
  std::cout << three.At(1, 2); // 0 at this time
}

具有相同参数的第二个非常量 At 方法返回对相应矩阵单元格中的值的引用

#include <iostream>

int main() {
  Matrix three(3, 4);
  three.At(1, 2) = 8;
  std::cout << three.At(1, 2); // 8
}

最后让我们实现&gt;&gt; 操作符:

#include <iostream>

std::istream& operator>>(std::istream& stream, Matrix &matrix) {
  int row = 0, col = 0;

  stream >> row >> col;
  matrix.Reset(row, col);

  for (int r = 0; r < row; ++r) {
    for (int c = 0; c < col; ++c) {
      stream >> matrix.At(r, c);
    }
  }

  return stream;
}

并对其进行测试:

#include <iostream>

int main() {
  Matrix four; // An empty matrix

  MatrixInfo(four);
  // Example output:
  //
  // { "rows": 0, "cols": 0 }

  std::cin >> four;
  // Example input
  //
  // 2 3
  // 4 -1 10
  // 8 7 13

  MatrixInfo(four);
  // Example output:
  //
  // { "rows": 2, "cols": 3 }
}

随意添加超出范围检查。我希望这个例子对你有帮助:)

【讨论】:

    【解决方案5】:

    试试这个。 m = row, n = col

    vector<vector<int>> matrix(m, vector<int>(n));
    
    for(i = 0;i < m; i++)
    {
       for(j = 0; j < n; j++)
       {
          cin >> matrix[i][j];
       }
       cout << endl;
    }
    cout << "::matrix::" << endl;
    for(i = 0; i < m; i++)
    {
        for(j = 0; j < n; j++)
        {
            cout << matrix[i][j] << " ";
        }
        cout << endl;
    }
    

    【讨论】:

      【解决方案6】:

      Vector 在作为cin&gt;&gt;v[i][j] 使用之前需要进行初始化。即使是一维向量,也需要初始化,see this link

      初始化后不会出错,see this link

      【讨论】:

      • 其实它已经初始化但是长度为“0”,所以它给出了SIGSEGV错误。
      【解决方案7】:

      你初始化的是一个向量的向量,所以你一定要包含一个要插入的向量(向量术语中的“Pushed”)在原始向量中您在示例中命名了矩阵。

      还有一件事,您不能使用运算符“cin”直接在向量中插入值。使用一个接受输入的变量,然后将其插入向量中。

      请试试这个:

      int num;
      for(int i=0; i<RR; i++){
      
            vector<int>inter_mat;       //Intermediate matrix to help insert(push) contents of whole row at a time
      
            for(int j=0; j<CC; j++){
                 cin>>num;             //Extra variable in helping push our number to vector
                 vin.push_back(num);   //Inserting numbers in a row, one by one 
                }
      
            v.push_back(vin);          //Inserting the whole row at once to original 2D matrix 
      }
      

      【讨论】:

        【解决方案8】:

        我为此开设了这门课。当添加更多项目时,它会产生一个可变大小的矩阵(可扩展)

        '''

        #pragma once
        #include<vector>
        #include<iostream>
        #include<iomanip>
        using namespace std;
        template <class T>class Matrix
        {
        public:
            Matrix() = default;
            bool AddItem(unsigned r, unsigned c, T value)
            {
                if (r >= Rows_count)
                {
                    Rows.resize(r + 1);
                    Rows_count = r + 1;
                }
                else
                {
                    Rows.resize(Rows_count);
                }
                if (c >= Columns_Count )
                {
                    for (std::vector<T>& row : Rows)
                    {
                        row.resize(c + 1);
                    }
                    Columns_Count = c + 1;
                }
                else
                {
                    for (std::vector<T>& row : Rows)
                    {
                        row.resize(Columns_Count);
                    }
                }
                if (r < Rows.size())
                    if (c < static_cast<std::vector<T>>(Rows.at(r)).size())
                    {
                        (Rows.at(r)).at(c) = value;
                    }
                    else
                    {
                        cout << Rows.at(r).size() << " greater than " << c << endl;
                    }
                else
                    cout << "ERROR" << endl;
                return true;
            }
            void Show()
            {
                std::cout << "*****************"<<std::endl;
                for (std::vector<T> r : Rows)
                {
                    for (auto& c : r)
                        std::cout << " " <<setw(5)<< c;
                    std::cout << std::endl;
                }
                std::cout << "*****************" << std::endl;
            }
            void Show(size_t n)
            {
                std::cout << "*****************" << std::endl;
                for (std::vector<T> r : Rows)
                {
                    for (auto& c : r)
                        std::cout << " " << setw(n) << c;
                    std::cout << std::endl;
                }
                std::cout << "*****************" << std::endl;
            }
        //  ~Matrix();
        public:
            std::vector<std::vector<T>> Rows;
            unsigned Rows_count;
            unsigned Columns_Count;
        };
        

        '''

        【讨论】:

          猜你喜欢
          • 2014-07-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-01-16
          • 2021-08-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多