C++ 矩阵到动态二维数组
C++ Matrix to dynamic 2D arrray
假设我们在 matrix.txt 文件中有一个矩阵,存储方式如下:
我们想将其转换为:
数字 8(第一个数字)表示二维数组有多大。之后它的意思是:
1连接到2(connection的值为1,永远为1)
1 连接到 8
3 连接到 4
当转换为二维动态数组时,我们需要 ARRRAY 0,1...0,7...2,3 中的值 1 等等(我没有使用方括号,因为 Whosebug 将它们读取为链接).
int number;
int **a = new int*[number];
for (int i = 0; i<number; i++) {
a[i] = new int[number];
}
for (int i = 0; i<number; i++) {
delete[]a[i];
}
delete[]a;
string line;
ifstream myfile("matrix.txt");
if (myfile.is_open())
{
getline(myfile, line);
istringstream(line)>> number;
while (getline(myfile, line)){
cout << line << '\n';
//HERE I SHOULD TURN THOSE NUMBERS INTO VALUES IN 2D ARRAY
}
myfile.close();
}
所以我的问题是:如何将这些数字转换为二维数组中的矩阵?
谢谢
我建议您使用来自 STL 的 C++ 向量而不是不安全的 2d C 数组。
你可以这样做:
ifstream myfile("matrix.txt");
// Read matrix size
size_t matrix_size = 0; myfile >> matrix_size;
vector<vector<int> > matrix(matrix_size);
for(size_t i=0; i < matrix.size(); ++i) matrix[i].resize(matrix_size);
while( myfile.good() )
{
// Read row,col,val and set matrix value
int row=0, col=0, val=0; myfile >> row >> col >> val;
--row; --col; // Since your indices go from 1 to N
if(row < matrix_size && row >= 0 && col < matrix_size && col >= 0) {
matrix[row][col] = val; matrix[col][row] = val;
}
}
最简单但可能不是最快的方法是将行写入 std::stringstream,然后从字符串流读回行、列和值变量。如果您正在从文件中读取,首先读取文件的成本通常比以缓慢的方式解析文件的成本相形见绌。如果这对您的情况很重要(并首先分析代码以确保它确实如此),请考虑手动解析文件。也就是说,这个基本逻辑是成立的。
while (getline(myfile, line)){
cout << line << '\n';
std::stringstream linestream(line);
int row;
int column;
int value;
if (linestream >> row >> column >> value)
{
a[row-1][column-1] = value;
a[column-1][row-1] = value;// mirror
}
else
{
// handle file formatting error
}
}
题外话,考虑使用矩阵 class 为您管理 a 而不是原始二维数组。 The matrix class here at isocppp.org is good and fast,以及一些非常好的通用建议。
上面带有 isocpp 矩阵的代码如下所示:
while (getline(myfile, line)){
cout << line << '\n';
std::stringstream linestream(line);
int row;
int column;
int value;
if (linestream >> row >> column >> value)
{
a(row-1,column-1) = value;
a(column-1,row-1) = value;// mirror
}
else
{
// handle file formatting error
}
}
几乎相同并且更易于使用,因为您不必担心自己管理内存、传递数组维度或一些错误代码(例如 a[4] = 0;
)数组的行。
附录
这个代码
int number;
int **a = new int*[number];
for (int i = 0; i<number; i++) {
a[i] = new int[number];
}
for (int i = 0; i<number; i++) {
delete[]a[i];
}
delete[]a;
有两个严重的问题:
a
大小为 number
,number
尚未分配。 number
可以是任何东西,从一个立即致命的负数(不能有一个负数大小的数组)到一个可能致命的巨大数字(您的计算机有 9,223,372,036,854,775,807 平方字节的 RAM?我不这么认为。)
- 分配存储后立即删除。释放内存是一个很好的养成习惯,但最好在使用后释放内存,而不是之前。
所以:
// define `a` here
string line;
ifstream myfile("matrix.txt");
if (myfile.is_open())
{
getline(myfile, line);
istringstream(line)>> number;
// allocate storage for `a` here
while (getline(myfile, line)){
cout << line << '\n';
//line reading code goes here
}
myfile.close();
}
// delete `a` somewhere down here after it's been used.
假设我们在 matrix.txt 文件中有一个矩阵,存储方式如下:
我们想将其转换为:
数字 8(第一个数字)表示二维数组有多大。之后它的意思是: 1连接到2(connection的值为1,永远为1) 1 连接到 8 3 连接到 4
当转换为二维动态数组时,我们需要 ARRRAY 0,1...0,7...2,3 中的值 1 等等(我没有使用方括号,因为 Whosebug 将它们读取为链接).
int number;
int **a = new int*[number];
for (int i = 0; i<number; i++) {
a[i] = new int[number];
}
for (int i = 0; i<number; i++) {
delete[]a[i];
}
delete[]a;
string line;
ifstream myfile("matrix.txt");
if (myfile.is_open())
{
getline(myfile, line);
istringstream(line)>> number;
while (getline(myfile, line)){
cout << line << '\n';
//HERE I SHOULD TURN THOSE NUMBERS INTO VALUES IN 2D ARRAY
}
myfile.close();
}
所以我的问题是:如何将这些数字转换为二维数组中的矩阵?
谢谢
我建议您使用来自 STL 的 C++ 向量而不是不安全的 2d C 数组。
你可以这样做:
ifstream myfile("matrix.txt");
// Read matrix size
size_t matrix_size = 0; myfile >> matrix_size;
vector<vector<int> > matrix(matrix_size);
for(size_t i=0; i < matrix.size(); ++i) matrix[i].resize(matrix_size);
while( myfile.good() )
{
// Read row,col,val and set matrix value
int row=0, col=0, val=0; myfile >> row >> col >> val;
--row; --col; // Since your indices go from 1 to N
if(row < matrix_size && row >= 0 && col < matrix_size && col >= 0) {
matrix[row][col] = val; matrix[col][row] = val;
}
}
最简单但可能不是最快的方法是将行写入 std::stringstream,然后从字符串流读回行、列和值变量。如果您正在从文件中读取,首先读取文件的成本通常比以缓慢的方式解析文件的成本相形见绌。如果这对您的情况很重要(并首先分析代码以确保它确实如此),请考虑手动解析文件。也就是说,这个基本逻辑是成立的。
while (getline(myfile, line)){
cout << line << '\n';
std::stringstream linestream(line);
int row;
int column;
int value;
if (linestream >> row >> column >> value)
{
a[row-1][column-1] = value;
a[column-1][row-1] = value;// mirror
}
else
{
// handle file formatting error
}
}
题外话,考虑使用矩阵 class 为您管理 a 而不是原始二维数组。 The matrix class here at isocppp.org is good and fast,以及一些非常好的通用建议。
上面带有 isocpp 矩阵的代码如下所示:
while (getline(myfile, line)){
cout << line << '\n';
std::stringstream linestream(line);
int row;
int column;
int value;
if (linestream >> row >> column >> value)
{
a(row-1,column-1) = value;
a(column-1,row-1) = value;// mirror
}
else
{
// handle file formatting error
}
}
几乎相同并且更易于使用,因为您不必担心自己管理内存、传递数组维度或一些错误代码(例如 a[4] = 0;
)数组的行。
附录
这个代码
int number;
int **a = new int*[number];
for (int i = 0; i<number; i++) {
a[i] = new int[number];
}
for (int i = 0; i<number; i++) {
delete[]a[i];
}
delete[]a;
有两个严重的问题:
a
大小为number
,number
尚未分配。number
可以是任何东西,从一个立即致命的负数(不能有一个负数大小的数组)到一个可能致命的巨大数字(您的计算机有 9,223,372,036,854,775,807 平方字节的 RAM?我不这么认为。)- 分配存储后立即删除。释放内存是一个很好的养成习惯,但最好在使用后释放内存,而不是之前。
所以:
// define `a` here
string line;
ifstream myfile("matrix.txt");
if (myfile.is_open())
{
getline(myfile, line);
istringstream(line)>> number;
// allocate storage for `a` here
while (getline(myfile, line)){
cout << line << '\n';
//line reading code goes here
}
myfile.close();
}
// delete `a` somewhere down here after it's been used.