(C++) 有没有办法在循环中创建不同的矩阵?
(C++) Is there a way to create different matrices in a loop?
我正在编写一个代码来读取文本文件以动态创建矩阵。然后我将从这个矩阵中获取信息并将其写入另一个文本文件。
我放入一个 'for' 循环,为它读取的每个文本块创建一个矩阵,这里是:
for (cont = 0; cont < nPares; cont++){
ResultFile >> FlowOri;
ResultFile >> FlowDest;
ResultFile >> nPaths;
ResultFile >> largestPath;
double** iPathMatrix = (double**) new double[nPaths];
for (i = 0; i < nPaths; i++) {
iPathMatrix[i] = (double*) new double[largestPath + 2];
}
for (i = 0; i < nPaths; i++) {
for (j = 0; j < largestPath + 2; j++) {
ResultFile >> iPathMatrix[i][j];
}
}
for (i = 0; i < nPaths; i++) {
for (j = 0; j < largestPath + 2; j++) {
cout << iPathMatrix[i][j] << " ";
}
cout << "\n";
}
free(iPathMatrix);
}
'ResultFile' 是一个 ifstream。
接近尾声的 'cout' 放在那里是为了检查它是否按预期创建了矩阵,确实如此。
如您所见,我正在创建矩阵,然后在循环结束时释放内存以再次创建它,因为它将具有相同的名称。我可能想出一种方法来处理这个,但如果我可以为每个循环创建一个不同的矩阵,它会更容易,如果可能的话,也许用 'FlowOri' 和 'FlowDest' 变量命名每个,并在循环停止后,访问它们并写入我的输出文件。
有办法吗?以后怎么引用呢?
As you can see, I'm creating the matrix and then freeing the memory at
the end of the loop to create it again,
不,你不是(至少不正确)。每个new[]必须和一个delete[]配对,所以正确的代码是
for (i = 0; i < nPaths; i++) {
delete[] iPathMatrix[i];
}
delete[] iPathMatrix;
既然你在用 C++ 编程,你可以通过使用向量来避免这种情况。
std::vector<std::vector<double>> iPathMatrix(nPaths, std::vector<double>(largestPath + 2));
现在你不需要分配或释放任何东西,但你的代码的其余部分没有改变。
现在谈谈你的实际问题。如果我理解正确的话,您想将矩阵与 flowOri
变量的值相关联。这很容易做到,你应该使用 std::map
.
你没有说 flowOri
是什么类型,我假设它是 std::string
但你应该能够让它工作,无论它是什么类型。
#include <vector>
#include <map>
#include <string>
// lets give a shorter name for the vector type
using MatrixRowType = std::vector<double>;
using MatrixType = std::vector<MatrixRowType>;
// and this is the map type that holds the matrices
using MatrixMapType = std::map<std::string, MatrixType>;
...
MatrixMapType matrixMap;
for (cont = 0; cont < nPares; cont++){
// read stuff
ResultFile >> FlowOri;
...
// read the matrix
MatrixType iPathMatrix(nPaths, MatrixRowType(largestPath + 2));
...
// save the matrix in the map keyed by FlowOri
matrixMap[FlowOri] = iPathMatrix;
}
现在当你想要检索矩阵时,你只需编写 matrixMap[something]
其中 something
是一个变量,其中包含你要检索的矩阵的名称。
变量名只对程序员有意义,除非您使用调试模式,否则从可执行文件中消失,因此 C++ 不允许创建动态命名 变量。无论如何,即使使用允许它的语言,它也是一个糟糕的设计。
但您始终可以创建任何对象类型的数组(或更好的向量)。因此,如果您想将所有内容存储在循环中并稍后处理整个数据,您可以使用 3 级向量。借助引用的魔力,您的代码几乎无需更改:
std::vector<std::vector<std::vector<double>>> matrixes(nPares);
for (auto& iPathMatrix : matrixes) { // iPathMatrix is a reference inside matrixes
ResultFile >> FlowOri;
ResultFile >> FlowDest;
ResultFile >> nPaths;
ResultFile >> largestPath;
iPathMatrix = std::vector<std::vector<double>>(nPaths);
for (i = 0; i < nPaths; i++) {
iPathMatrix[i] = std::vector<double>(largestPath + 2];
}
for (i = 0; i < nPaths; i++) {
for (j = 0; j < largestPath + 2; j++) {
ResultFile >> iPathMatrix[i][j];
}
}
}
// control:
for (int i = 0; i < nPares; i++) {
for (int j = 0; j < matrixes[i].size(); j++) {
for (int k = 0; k < matrixes[i][j].size(); k++) {
std::cout << matrixes[i][j][k] << " ";
}
std::cout << '\n';
}
std::cout << '\n';
}
matrixes
现在包含您的所有数据
我正在编写一个代码来读取文本文件以动态创建矩阵。然后我将从这个矩阵中获取信息并将其写入另一个文本文件。
我放入一个 'for' 循环,为它读取的每个文本块创建一个矩阵,这里是:
for (cont = 0; cont < nPares; cont++){
ResultFile >> FlowOri;
ResultFile >> FlowDest;
ResultFile >> nPaths;
ResultFile >> largestPath;
double** iPathMatrix = (double**) new double[nPaths];
for (i = 0; i < nPaths; i++) {
iPathMatrix[i] = (double*) new double[largestPath + 2];
}
for (i = 0; i < nPaths; i++) {
for (j = 0; j < largestPath + 2; j++) {
ResultFile >> iPathMatrix[i][j];
}
}
for (i = 0; i < nPaths; i++) {
for (j = 0; j < largestPath + 2; j++) {
cout << iPathMatrix[i][j] << " ";
}
cout << "\n";
}
free(iPathMatrix);
}
'ResultFile' 是一个 ifstream。 接近尾声的 'cout' 放在那里是为了检查它是否按预期创建了矩阵,确实如此。
如您所见,我正在创建矩阵,然后在循环结束时释放内存以再次创建它,因为它将具有相同的名称。我可能想出一种方法来处理这个,但如果我可以为每个循环创建一个不同的矩阵,它会更容易,如果可能的话,也许用 'FlowOri' 和 'FlowDest' 变量命名每个,并在循环停止后,访问它们并写入我的输出文件。
有办法吗?以后怎么引用呢?
As you can see, I'm creating the matrix and then freeing the memory at the end of the loop to create it again,
不,你不是(至少不正确)。每个new[]必须和一个delete[]配对,所以正确的代码是
for (i = 0; i < nPaths; i++) {
delete[] iPathMatrix[i];
}
delete[] iPathMatrix;
既然你在用 C++ 编程,你可以通过使用向量来避免这种情况。
std::vector<std::vector<double>> iPathMatrix(nPaths, std::vector<double>(largestPath + 2));
现在你不需要分配或释放任何东西,但你的代码的其余部分没有改变。
现在谈谈你的实际问题。如果我理解正确的话,您想将矩阵与 flowOri
变量的值相关联。这很容易做到,你应该使用 std::map
.
你没有说 flowOri
是什么类型,我假设它是 std::string
但你应该能够让它工作,无论它是什么类型。
#include <vector>
#include <map>
#include <string>
// lets give a shorter name for the vector type
using MatrixRowType = std::vector<double>;
using MatrixType = std::vector<MatrixRowType>;
// and this is the map type that holds the matrices
using MatrixMapType = std::map<std::string, MatrixType>;
...
MatrixMapType matrixMap;
for (cont = 0; cont < nPares; cont++){
// read stuff
ResultFile >> FlowOri;
...
// read the matrix
MatrixType iPathMatrix(nPaths, MatrixRowType(largestPath + 2));
...
// save the matrix in the map keyed by FlowOri
matrixMap[FlowOri] = iPathMatrix;
}
现在当你想要检索矩阵时,你只需编写 matrixMap[something]
其中 something
是一个变量,其中包含你要检索的矩阵的名称。
变量名只对程序员有意义,除非您使用调试模式,否则从可执行文件中消失,因此 C++ 不允许创建动态命名 变量。无论如何,即使使用允许它的语言,它也是一个糟糕的设计。
但您始终可以创建任何对象类型的数组(或更好的向量)。因此,如果您想将所有内容存储在循环中并稍后处理整个数据,您可以使用 3 级向量。借助引用的魔力,您的代码几乎无需更改:
std::vector<std::vector<std::vector<double>>> matrixes(nPares);
for (auto& iPathMatrix : matrixes) { // iPathMatrix is a reference inside matrixes
ResultFile >> FlowOri;
ResultFile >> FlowDest;
ResultFile >> nPaths;
ResultFile >> largestPath;
iPathMatrix = std::vector<std::vector<double>>(nPaths);
for (i = 0; i < nPaths; i++) {
iPathMatrix[i] = std::vector<double>(largestPath + 2];
}
for (i = 0; i < nPaths; i++) {
for (j = 0; j < largestPath + 2; j++) {
ResultFile >> iPathMatrix[i][j];
}
}
}
// control:
for (int i = 0; i < nPares; i++) {
for (int j = 0; j < matrixes[i].size(); j++) {
for (int k = 0; k < matrixes[i][j].size(); k++) {
std::cout << matrixes[i][j][k] << " ";
}
std::cout << '\n';
}
std::cout << '\n';
}
matrixes
现在包含您的所有数据